【问题标题】:Is this duck-typing in Python?这是 Python 中的鸭子类型吗?
【发布时间】:2013-06-06 09:28:10
【问题描述】:

这是一些 Ruby 代码:

class Duck
  def help
    puts "Quaaaaaack!"
  end
end

class Person
  def help
    puts "Heeeelp!"
  end
end

def InTheForest x
  x.help
end

donald = Duck.new
john = Person.new
print "Donald in the forest: "
InTheForest donald
print "John in the forest: "
InTheForest john

而且,我把它翻译成 Python:

import sys

class Duck:
        def help():
            print("Quaaaaaack!")

class Person:
        def help():
            print("Heeeelp!")

def InTheForest(x):
    x.help()

donald = Duck()
john = Person()
sys.stdout.write("Donald in the forest: ")
InTheForest(donald)
sys.stdout.write("John in the forest: ")
InTheForest(john)

结果是一样的。这是否意味着我的 Python 代码正在使用鸭子类型?我找不到鸭子类型的例子,所以我认为Python中可能没有鸭子类型。维基百科里有code,但是我看不懂。

【问题讨论】:

  • Python 完全是关于鸭子类型的。你写的例子很典型。
  • @darxsys 那么为什么没有这样的例子呢?维基百科上有一个代码,但我不明白它是如何工作的

标签: python python-3.x duck-typing


【解决方案1】:

代码并未显示全部内容。鸭子打字是关于尝试一些事情并在发生异常时处理它们。只要它嘎嘎叫,就当做鸭子,否则就另当别论。

try:
    dog.quack()
except AttributeError:
    dog.woof()

wikipedia Duck_typing article 顶部在描述非鸭子类型语言之后解释了此行为:

在鸭子类型的语言中,等效函数将获取任何类型的对象并调用该对象的 walk 和 quack 方法。如果对象没有被调用的方法,则该函数会发出运行时错误信号。如果对象确实有方法,那么无论对象的类型如何,它们都会被执行,从而唤起引号,从而产生这种类型的名称。

你的例子:

class Person:
    def help(self):
        print("Heeeelp!")

class Duck:
    def help(self):
        print("Quaaaaaack!")

class SomethingElse:
    pass

def InTheForest(x):
    x.help()

donald = Duck()
john = Person()
who = SomethingElse()

for thing in [donald, john, who]:
    try:
        InTheForest(thing)
    except AttributeError:
        print 'Meeowww!'

输出:

Quaaaaaack!
Heeeelp!
Meeowww!

【讨论】:

    【解决方案2】:

    是的,这是鸭子类型,Python 代码可以(并且经常)使用它。

    http://en.wikipedia.org/wiki/Duck_typing#In_Python

    页面上方有一个更完整的 Python 示例:

    class Duck:
        def quack(self):
            print("Quaaaaaack!")
        def feathers(self):
            print("The duck has white and gray feathers.")
    
    class Person:
        def quack(self):
            print("The person imitates a duck.")
        def feathers(self):
            print("The person takes a feather from the ground and shows it.")
        def name(self):
            print("John Smith")
    
    def in_the_forest(duck):
        duck.quack()
        duck.feathers()
    
    def game():
        donald = Duck()
        john = Person()
        in_the_forest(donald)
        in_the_forest(john)
    
    game()
    

    【讨论】:

    • 我无法理解维基百科的代码,这就是我问的原因
    【解决方案3】:

    当您在 Python 中定义一个方法时,您必须提供它所应用的对象,在您的例子中是 self

    因此,您必须使用以下行调整您的代码以获得预期的行为:

    class Duck:
        def help(self):
            print("Quaaaaaack!")
    
    class Person:
        def help(self):
            print("Heeeelp!")
    

    【讨论】:

    • 是的,但不是答案。另外,正如 OP 所说“结果是一样的”,我假设错误只出现在问题的代码中,而不是 OP 的实际代码中。
    • 我明白它是如何工作的,我只是在 python 中找不到使用鸭子打字的例子......我在谷歌搜索但找不到结果然后我试图将 ruby​​ 翻译成 python 并且它工作..我是只是好奇我写的是不是鸭子打字。
    猜你喜欢
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    相关资源
    最近更新 更多