鸭子打字与基于 class 的继承
Duck typing Vs class based Inheritance
使用 DuckTyping 方法,下面是两个 classes Duck
& Person
,
class Duck:
def quack(self):
print('Quack')
def fly(self):
print('Flap')
class Person:
def quack(self):
print('I\'m quacking like a duck')
def walk(self):
print('Walk')
def quackFlap(creature):
try:
creature.quack()
except: # EAFP
print('Cannot quack')
try:
creature.flap() # Using hasattr() will violate EAFP
except: # EAFP
print('Cannot flap')
donald = Duck()
quackFlap(donald)
p = Person()
quackFlap(p) # Duck Typing approach says, Person is not Duck.
使用基于class的继承方法,下面是两个classes Bird
& Duck
,
class Bird(object):
def quack(self):
print('Quack')
def fly(self):
print('Fly')
class Duck(Bird):
def quack(self):
print('I\'m quacking like a duck')
def fly(self):
print('Flap')
def quackFlap(creature):
if isinstance(creature, Bird):
creature.quack()
creature.flap()
b = Bird()
quackFlap(b)
d = Duck()
quackFlap(d) # Inheritance allowed isinstance() check - Error handling
问题:
1) DuckTyping 是否避免了 Subclassing?因为在 subclassing 上,我们没有看到 DuckTyping 方法的必要性
2) DuckTyping 何时优于基于 class 的继承?
1) Does DuckTyping avoid Subclassing? because on subclassing, we do
not the necessity of DuckTyping approach
完全没有。当您需要访问超类上未定义的内容时,鸭子类型只会对子类类型进行不必要的 casts/checkings 操作。但是通过良好的设计和正确使用多态性,您可以避免这样做(使用 instanceof + cast 来访问子类的特殊性)。
2) When DuckTyping is better than class based inheritance?
这真的取决于...当 类 之间没有 "IS A" 关系时,应避免继承,主要是当它仅用作重新利用代码的手段时。如果存在 "IS A" 关系,并且代码依赖于 "instanceof" 的使用,则表明设计不当,即未正确使用多态性。
Duck typing 是一种无需依赖抽象 classes/interfaces(例如 Java)即可获得多态代码的简便方法。但是一个抽象 class/interface 定义了一个契约。使用鸭子类型,由于缺乏正式关系,您可以在代码中引入细微的错误。如果你的 "quack" 根本不是 "quack",你就有麻烦了。使用继承,由于子类化抽象的契约性质,这种情况不太可能发生 类.
使用 DuckTyping 方法,下面是两个 classes Duck
& Person
,
class Duck:
def quack(self):
print('Quack')
def fly(self):
print('Flap')
class Person:
def quack(self):
print('I\'m quacking like a duck')
def walk(self):
print('Walk')
def quackFlap(creature):
try:
creature.quack()
except: # EAFP
print('Cannot quack')
try:
creature.flap() # Using hasattr() will violate EAFP
except: # EAFP
print('Cannot flap')
donald = Duck()
quackFlap(donald)
p = Person()
quackFlap(p) # Duck Typing approach says, Person is not Duck.
使用基于class的继承方法,下面是两个classes Bird
& Duck
,
class Bird(object):
def quack(self):
print('Quack')
def fly(self):
print('Fly')
class Duck(Bird):
def quack(self):
print('I\'m quacking like a duck')
def fly(self):
print('Flap')
def quackFlap(creature):
if isinstance(creature, Bird):
creature.quack()
creature.flap()
b = Bird()
quackFlap(b)
d = Duck()
quackFlap(d) # Inheritance allowed isinstance() check - Error handling
问题:
1) DuckTyping 是否避免了 Subclassing?因为在 subclassing 上,我们没有看到 DuckTyping 方法的必要性
2) DuckTyping 何时优于基于 class 的继承?
1) Does DuckTyping avoid Subclassing? because on subclassing, we do not the necessity of DuckTyping approach
完全没有。当您需要访问超类上未定义的内容时,鸭子类型只会对子类类型进行不必要的 casts/checkings 操作。但是通过良好的设计和正确使用多态性,您可以避免这样做(使用 instanceof + cast 来访问子类的特殊性)。
2) When DuckTyping is better than class based inheritance?
这真的取决于...当 类 之间没有 "IS A" 关系时,应避免继承,主要是当它仅用作重新利用代码的手段时。如果存在 "IS A" 关系,并且代码依赖于 "instanceof" 的使用,则表明设计不当,即未正确使用多态性。
Duck typing 是一种无需依赖抽象 classes/interfaces(例如 Java)即可获得多态代码的简便方法。但是一个抽象 class/interface 定义了一个契约。使用鸭子类型,由于缺乏正式关系,您可以在代码中引入细微的错误。如果你的 "quack" 根本不是 "quack",你就有麻烦了。使用继承,由于子类化抽象的契约性质,这种情况不太可能发生 类.