对于从静态语言(java/c#)迁移到像 python 这样的动态语言的人来说,最大的问题是什么?
怎么做看起来很酷,但是重命名一个方法,或者添加/删除参数似乎太冒险了!
是为每种方法编写测试的唯一解决方案吗?
对于从静态语言(java/c#)迁移到像 python 这样的动态语言的人来说,最大的问题是什么?
怎么做看起来很酷,但是重命名一个方法,或者添加/删除参数似乎太冒险了!
是为每种方法编写测试的唯一解决方案吗?
“是为每种方法编写测试的唯一解决方案吗?”
你是说你没有为 Java 中的每个方法编写测试吗?
如果您在 Java 中为每个方法编写测试,那么 - 好吧 - 没有任何变化,不是吗?
重命名一个方法,看起来太冒险了!
正确的。不要这样做。
添加/删除参数似乎很冒险!
什么?您是在谈论可选参数吗?如果是这样,那么在 Java 中使用多个重载名称似乎是有风险和令人困惑的。具有可选参数似乎更简单。
如果你在 SO 上搜索最常见的 Python 问题,你会发现有些东西是长期存在的问题。
如何更新PYTHONPATH
.
为什么一些随机浮点计算与数学抽象可能表明的不同。
使用 Python 3 并输入 Python 2 教程中的代码。
为什么 Python 没有 super-complex和protected
声明。private
public
为什么 Python 没有枚举类型。
#1 的长期问题似乎是使用可变对象作为函数的默认值。简单地避免这种情况。
第一次尝试 Python 时让我印象深刻的一些事情(主要来自 Java 背景):
编写Pythonic代码。使用为 Python 推荐的习语,而不是使用旧的 Java/C 方式。这不仅仅是一个表面或教条问题。Pythonic 代码在实践中实际上比 C 类代码几乎一直快得多。事实上,恕我直言,很多“Python 很慢”的想法是由于没有经验的编码人员尝试在 Python 中编写 Java/C 并最终受到很大的性能影响,并认为 Python 是慢得可怕。尽可能使用列表推导和 map/filter/reduce。
对函数是真正的对象的想法感到满意。将它们作为回调传递,使函数返回函数,了解闭包等。
您可以在 Python 中做很多很酷且几乎是神奇的事情,比如您提到的重命名方法。这些东西很好地展示了 Python 的特性,但如果你不需要它们,真的没必要。事实上,正如 S. Lott 所指出的,最好避免看起来有风险的事情。
我会说第一个问题是尝试用动态语言编写静态类型的代码。
不要犹豫,使用标识符指向一个字符串,然后在自包含的代码部分中使用一个列表
keys = 'foo bar foobar' # Imagine this coming in as an argument
keys = keys.split() # Now the semantically chose name for the argument can be
# reused As the semantically chosen name for a local variable
不要犹豫,将函数视为常规值:它们是。采用以下解析器。假设我们想把所有的header标签都当作ol标签一样对待,ul标签像ol标签一样对待。
class Parser(HTMLParser):
def __init__(self, html):
self.feed(html)
def handle_starttag(self, tag, attrs):
parse_method = 'parse_' + tag
if hasattr(self, parse_method):
getattr(self, parse_method)(attrs)
def parse_list(self, attrs):
# generic code
def parse_header(self, attrs):
# more generic code
parse_h1 = parse_h2 = parse_h3 = parse_h4 = parse_h5 = parse_h6 = parse_header
parse_ol = parse_ul = parse_list
这可以通过在handle_starttag
java 之类的语言中使用较少通用的代码来完成,方法是跟踪哪些标签映射到同一个方法,但是如果您决定要处理 div 标签,则必须将其添加到调度逻辑中. 在这里,您只需添加方法parse_div
,您就可以开始了。
不要打字检查!鸭式!
def funtion(arg):
if hasattr(arg, 'attr1') and hasattr(arg, 'attr2'):
foo(arg):
else:
raise TypeError("arg must have 'attr1' and 'attr2'")
与isinstance(arg, Foo)
. attr1
这使您可以使用和传递任何对象attr2
。例如,这允许您传入一个包裹在对象周围的跟踪类以进行调试。您必须修改该类才能在 Java AFAIK 中执行此操作。
正如 THC4k 所指出的,另一种(更 Pythonic)的方法是EAPF成语。我不喜欢这样,因为我喜欢尽早发现错误。如果您希望代码很少失败,那么它会更有效。不要告诉任何人我不喜欢它,尽管他们会停止认为我知道如何编写 python。这是 THC4k 提供的示例。
try:
foo(arg):
except (AttributeError, TypeError):
raise InvalidArgumentError(foo, arg)
关于我们是否应该捕获AttributeError
andTypeError
或者只是让它们传播到知道如何处理它们的地方,这是一个折腾,但这只是一个例子,所以我们让它飞起来。