Python 不理解类型检查的糟糕形式-duck类型
我有一个函数,它需要根据所接受的参数的类型做出不同的行为。我的第一个冲动是加入一些对iInstance的调用,但我一直在stackoverflow上看到答案,说这是糟糕的形式和非音速的,但没有太多的理由说明为什么它是糟糕的形式和非音速的。对于后者,我想它与duck类型有关,但是检查您的参数是否属于特定类型又有什么大不了的呢?安全行事不是更好吗 使用Python 不理解类型检查的糟糕形式-duck类型,python,python-2.7,typechecking,Python,Python 2.7,Typechecking,我有一个函数,它需要根据所接受的参数的类型做出不同的行为。我的第一个冲动是加入一些对iInstance的调用,但我一直在stackoverflow上看到答案,说这是糟糕的形式和非音速的,但没有太多的理由说明为什么它是糟糕的形式和非音速的。对于后者,我想它与duck类型有关,但是检查您的参数是否属于特定类型又有什么大不了的呢?安全行事不是更好吗 使用isinstance限制可以传递给函数的对象。例如: def add(a,b): if isinstance(a,int) and isins
isinstance
限制可以传递给函数的对象。例如:
def add(a,b):
if isinstance(a,int) and isinstance(b,int):
return a + b
else:
raise ValueError
现在,您可以尝试将其命名为:
add(1.0,2)
期望得到3
,但却得到一个错误,因为1.0
不是整数。显然,在这里使用isinstance
会妨碍函数发挥应有的作用。最终,如果我们烤的东西尝起来像鸭子,我们不在乎它们是什么类型的,只要它们能用
然而,在有些情况下,情况正好相反:
def read(f):
if isinstance(f,basestring):
with open(f) as fin
return fin.read()
else:
return f.read()
关键是,您需要确定希望函数具有的API。函数的行为应根据类型而有所不同的情况是存在的,但很少见(我知道,检查字符串以打开文件是更常见的用法之一)。使用
isinstance
限制可以传递给函数的对象。例如:
def add(a,b):
if isinstance(a,int) and isinstance(b,int):
return a + b
else:
raise ValueError
现在,您可以尝试将其命名为:
add(1.0,2)
期望得到3
,但却得到一个错误,因为1.0
不是整数。显然,在这里使用isinstance
会妨碍函数发挥应有的作用。最终,如果我们烤的东西尝起来像鸭子,我们不在乎它们是什么类型的,只要它们能用
然而,在有些情况下,情况正好相反:
def read(f):
if isinstance(f,basestring):
with open(f) as fin
return fin.read()
else:
return f.read()
关键是,您需要确定希望函数具有的API。函数的行为应该根据类型而有所不同的情况是存在的,但这种情况很少见(我知道,检查字符串以打开文件是更常见的用法之一)。因为这样做明确地防止了duck类型 这里有一个例子。
csv
模块允许我以csv格式将数据写入文件。因此,函数接受文件作为参数。但是,如果我不想写入实际的文件,而是写入类似于StringIO
对象的东西,该怎么办?这是一个非常好的用法,因为StringIO
实现了必要的读写方法。但是,如果csv
明确检查类型为file
的实际对象,那么这将被禁止
一般来说,Python认为我们应该尽可能多地允许一些事情——这与类中缺少真正的私有变量的原因是一样的。因为这样做显式地防止了duck类型 这里有一个例子。
csv
模块允许我以csv格式将数据写入文件。因此,函数接受文件作为参数。但是,如果我不想写入实际的文件,而是写入类似于StringIO
对象的东西,该怎么办?这是一个非常好的用法,因为StringIO
实现了必要的读写方法。但是,如果csv
明确检查类型为file
的实际对象,那么这将被禁止
一般来说,Python认为我们应该尽可能多地允许事情发生——这与类中缺少真正的私有变量的原因是一样的。有时使用isinstance只是重新实现多态分派。查看
str(…)
,它调用object.\uuu str\uuuu(…)
,每个类型都单独实现。通过实现\uuuu str\uuuu
,您可以通过扩展一个对象来重用依赖于str
的代码,而不必操作内置方法str(…)
基本上,这是OOP的顶点。你想要多态行为,你不想拼写类型
不过,使用它是有充分理由的。有时使用iInstance只是重新实现多态调度。查看
str(…)
,它调用object.\uuu str\uuuu(…)
,每个类型都单独实现。通过实现\uuuu str\uuuu
,您可以通过扩展一个对象来重用依赖于str
的代码,而不必操作内置方法str(…)
基本上,这是OOP的顶点。你想要多态行为,你不想拼写类型
不过,使用它有充分的理由。请咨询
我对此事的看法是:
- 如果您正在限制代码,请不要这样做
- 如果您使用它来指导代码,那么将其限制在非常特定的情况下
我对此事的看法是:
- 如果您正在限制代码,请不要这样做
- 如果您使用它来指导代码,那么将其限制在非常特定的情况下
那么你的问题是,duck打字的目的是什么?我想回答这个问题会帮助我澄清误解。请参阅,以获得良好的信息并与其他类型系统进行比较。那么你的问题是,duck打字的目的是什么?我想回答这个问题将有助于澄清我的误解。请参阅,以获得良好的信息以及与其他打字系统的比较。谢谢!那篇文章真的很棒。谢谢!那篇文章确实很棒。