Bla*_*man 6 python java dynamic-languages
对于从静态语言(java/c#)移动到动态语言(如python)的人来说,最重要的是什么?
如何完成任务似乎很酷,但重命名方法,或添加/删除参数似乎有风险!
是为每种方法编写测试的唯一解决方案吗?
我想说,第一个陷阱是尝试用动态语言编写静态类型代码。
毫不犹豫地使用标识符来指向字符串,然后在独立的代码部分中使用列表
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
Run Code Online (Sandbox Code Playgroud)
请毫不犹豫地将函数视为常规值:它们确实如此。采用以下解析器。假设我们想像对待所有 header 标签一样对待所有 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
Run Code Online (Sandbox Code Playgroud)
这可以通过在 java 等语言的方法中使用较少通用的代码来完成,方法handle_starttag是跟踪哪些标签映射到同一方法,但是如果您决定要处理 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'")
Run Code Online (Sandbox Code Playgroud)
与 相对isinstance(arg, Foo)。attr1这允许您使用和传入任何对象attr2。例如,这允许您传入包裹在对象周围的跟踪类以进行调试。在 Java 中,您必须修改该类才能执行此操作。
正如 THC4k 所指出的,另一种(更Pythonic)的方法是EAPF惯用法。我不喜欢这样,因为我喜欢尽早发现错误。如果您希望代码很少失败,那么效率会更高。不要告诉任何人我不喜欢它,尽管他们会不再认为我知道如何编写Python。这是 THC4k 提供的示例。
try:
foo(arg):
except (AttributeError, TypeError):
raise InvalidArgumentError(foo, arg)
Run Code Online (Sandbox Code Playgroud)
我们是否应该捕获它们AttributeError,TypeError或者只是让它们传播到知道如何处理它们的地方,这是一个难以抉择的问题,但这只是一个例子,所以我们就让它飞吧。