6

对于从静态语言(java/c#)迁移到像 python 这样的动态语言的人来说,最大的问题是什么?

怎么做看起来很酷,但是重命名一个方法,或者添加/删除参数似乎太冒险了!

是为每种方法编写测试的唯一解决方案吗?

4

3 回答 3

3

“是为每种方法编写测试的唯一解决方案吗?”

你是说你没有为 Java 中的每个方法编写测试吗?

如果您在 Java 中为每个方法编写测试,那么 - 好吧 - 没有任何变化,不是吗?

重命名一个方法,看起来太冒险了!

正确的。不要这样做。

添加/删除参数似乎很冒险!

什么?您是在谈论可选参数吗?如果是这样,那么在 Java 中使用多个重载名称似乎是有风险和令人困惑的。具有可选参数似乎更简单。


如果你在 SO 上搜索最常见的 Python 问题,你会发现有些东西是长期存在的问题。

  • 如何更新PYTHONPATH.

  • 为什么一些随机浮点计算与数学抽象可能表明的不同。

  • 使用 Python 3 并输入 Python 2 教程中的代码。

  • 为什么 Python 没有 super-complex和protected声明。privatepublic

  • 为什么 Python 没有枚举类型。

#1 的长期问题似乎是使用可变对象作为函数的默认值。简单地避免这种情况。

于 2010-09-13T19:33:28.977 回答
2

第一次尝试 Python 时让我印象深刻的一些事情(主要来自 Java 背景):

  1. 编写Pythonic代码。使用为 Python 推荐的习语,而不是使用旧的 Java/C 方式。这不仅仅是一个表面或教条问题。Pythonic 代码在实践中实际上比 C 类代码几乎一直快得多。事实上,恕我直言,很多“Python 很慢”的想法是由于没有经验的编码人员尝试在 Python 中编写 Java/C 并最终受到很大的性能影响,并认为 Python 是慢得可怕。尽可能使用列表推导和 map/filter/reduce。

  2. 对函数是真正的对象的想法感到满意。将它们作为回调传递,使函数返回函数,了解闭包等。

  3. 您可以在 Python 中做很多很酷且几乎是神奇的事情,比如您提到的重命名方法。这些东西很好地展示了 Python 的特性,但如果你不需要它们,真的没必要。事实上,正如 S. Lott 所指出的,最好避免看起来有风险的事情。

于 2010-09-13T20:04:58.443 回答
2

我会说第一个问题是尝试用动态语言编写静态类型的代码。

不要犹豫,使用标识符指向一个字符串,然后在自包含的代码部分中使用一个列表

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_starttagjava 之类的语言中使用较少通用的代码来完成,方法是跟踪哪些标签映射到同一个方法,但是如果您决定要处理 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)

关于我们是否应该捕获AttributeErrorandTypeError或者只是让它们传播到知道如何处理它们的地方,这是一个折腾,但这只是一个例子,所以我们让它飞起来。

于 2010-09-13T20:06:45.147 回答