Python 动态类型设计:处理列表的递归性是一个好的设计吗?

Python 动态类型设计:处理列表的递归性是一个好的设计吗?,python,list,coding-style,dynamic-typing,Python,List,Coding Style,Dynamic Typing,由于缺乏维护动态类型代码的经验,我正在寻找处理此类情况的最佳方法: (python中的示例,但可以与任何动态类型化语言一起使用) 我对此感到非常不安,因为我认为一个方法应该只做一件事,而且我认为它并不像应该的那样可读。因此,我想做三个函数:第一个函数将接受任何对象并在其他两个对象之间进行“排序”,一个用于列表,另一个用于“简单”对象。再说一次,这会增加一些复杂性 这里最“可持续”的解决方案是什么,以及保证易于维护的解决方案是什么?python中是否有一个我不知道的习惯用法?提前感谢。不要键入ch

由于缺乏维护动态类型代码的经验,我正在寻找处理此类情况的最佳方法:

(python中的示例,但可以与任何动态类型化语言一起使用)

我对此感到非常不安,因为我认为一个方法应该只做一件事,而且我认为它并不像应该的那样可读。因此,我想做三个函数:第一个函数将接受任何对象并在其他两个对象之间进行“排序”,一个用于列表,另一个用于“简单”对象。再说一次,这会增加一些复杂性


这里最“可持续”的解决方案是什么,以及保证易于维护的解决方案是什么?python中是否有一个我不知道的习惯用法?提前感谢。

不要键入check-做你想做的事情,如果它不起作用,它将抛出一个异常,你可以捕获并管理它

python的口号是“”。类型检查需要额外的时间,当大多数时间,它将是毫无意义的。在duck类型的环境中,它也没有多大意义——如果它有效,谁会在乎它为什么是duck类型呢?当其他iterables也可以使用时,为什么要将自己限制在列表中

例如:

这更具可读性,适用于更多情况(如果我传入任何其他不是列表的iterable,则会有很多),并且通常会更快

请注意,您正在混淆术语。Python是,但不是。弱类型表示对象根据需要更改类型。例如,如果您添加一个字符串和一个int,它会将该字符串转换为int来进行添加。Python不会这样做。动态类型意味着您不为变量声明类型,它可能在某个点包含字符串,然后是int

是一个术语,用于描述对象的使用,而不考虑其类型。如果它像鸭子一样走路,像鸭子一样呱呱叫,那么它很可能是一只鸭子


现在,这是一个一般性的问题,如果您认为您的代码获得对象的“错误”类型的频率比“正确”类型的频率更高,那么您可能需要对速度进行类型检查。请注意,这种情况很少见,最好避免过早优化。通过捕获异常,然后进行测试—如果您发现它是一个瓶颈,然后进行优化。

不要键入检查—执行您想执行的操作,如果它不起作用,它将抛出一个您可以捕获和管理的异常

python的口号是“”。类型检查需要额外的时间,当大多数时间,它将是毫无意义的。在duck类型的环境中,它也没有多大意义——如果它有效,谁会在乎它为什么是duck类型呢?当其他iterables也可以使用时,为什么要将自己限制在列表中

例如:

这更具可读性,适用于更多情况(如果我传入任何其他不是列表的iterable,则会有很多),并且通常会更快

请注意,您正在混淆术语。Python是,但不是。弱类型表示对象根据需要更改类型。例如,如果您添加一个字符串和一个int,它会将该字符串转换为int来进行添加。Python不会这样做。动态类型意味着您不为变量声明类型,它可能在某个点包含字符串,然后是int

是一个术语,用于描述对象的使用,而不考虑其类型。如果它像鸭子一样走路,像鸭子一样呱呱叫,那么它很可能是一只鸭子


现在,这是一个一般性的问题,如果您认为您的代码获得对象的“错误”类型的频率比“正确”类型的频率更高,那么您可能需要对速度进行类型检查。请注意,这种情况很少见,最好避免过早优化。捕获异常,然后进行测试—如果发现它是一个瓶颈,则进行优化。

在这种情况下,您可以使用decorator使其更易于维护:

from mm import multimethod

@multimethod(int, int)
def foo(a, b):
    ...code for two ints...

@multimethod(float, float):
def foo(a, b):
    ...code for two floats...

@multimethod(str, str):
def foo(a, b):
    ...code for two strings...

在这种情况下,您可以使用decorator使其更易于维护:

from mm import multimethod

@multimethod(int, int)
def foo(a, b):
    ...code for two ints...

@multimethod(float, float):
def foo(a, b):
    ...code for two floats...

@multimethod(str, str):
def foo(a, b):
    ...code for two strings...

通常的做法是通过对不同类型的输入使用不同的参数来实现多接口

def foo(thing=None, thing_seq=None):
    if thing_seq is not None:
        for _thing in thing_seq:
            foo(thing=_thing)
    if thing is not None:
        print "did foo with", thing

通常的做法是通过对不同类型的输入使用不同的参数来实现多接口

def foo(thing=None, thing_seq=None):
    if thing_seq is not None:
        for _thing in thing_seq:
            foo(thing=_thing)
    if thing is not None:
        print "did foo with", thing

我倾向于这样做,而不是递归进行:

def foo(x):
    if not isinstance(x, list):
        x = [x]
    for y in x:
        do_something(y)

我倾向于这样做,而不是递归进行:

def foo(x):
    if not isinstance(x, list):
        x = [x]
    for y in x:
        do_something(y)


Python是动态类型的,而不是弱类型的。什么是
某个函数
?在许多情况下,它可以应用于与简单对象相同的列表。@IgnacioVazquez Abrams:Oooops!这是正确的。事实上,这在很大程度上取决于
某个函数的功能。那么,如果你控制双方,那么要求参数为序列是否不合理?Python是动态类型的,而不是弱类型的。什么是
某个函数
?在许多情况下,它可以应用于与简单对象相同的列表。@IgnacioVazquez Abrams:Oooops!这是正确的。事实上,这很大程度上取决于
某些函数的功能。那么,如果你控制双方,要求参数是序列是否不合理?另外,使用isinstance也可以,如果你之前知道你可能会得到一个列表,例如,在迭代过程中,这种方法的一个常见问题是字符串是可编辑的,因此您可能需要显式的类型检查来捕获字符串。与异常处理相比,类型检查不会花费太多时间。此外,您正在捕获
TypeError
,但是不兼容的类型可能会引发
AttributeError
。尝试/except在时间上不是很昂贵吗?这是一件事——很多人都在为流控制使用异常而挣扎,因为它被其他语言的人认为是错误的。它实际上很有意义,它可以阻止比赛条件,在很多情况下它可以提供更好的性能(奇怪),而且它的阅读效果更好。试一试,如果它确实让你慢下来,以后再优化它,但我可以说99%的时候它可能不会是个问题。此外,使用iInstance也可以,当你知道之前你可能会得到一个列表时,例如…这是一个常见的问题