Hyp*_*eus 9 python static monkeypatching
直到一小时前,我确信在python Foo ().bar ()中只不过是一个简短的手,Foo.bar (Foo () )它将实例作为第一个参数传递.在这个例子中,最后两行(显然)做同样的事情:
class Foo (object):
def bar (self): print "baz"
qux = Foo ()
qux.bar ()
Foo.bar (qux)
Run Code Online (Sandbox Code Playgroud)
但是现在我有一个类Animal,它有一个静态方法populate(),它返回man已知的所有动物的列表.此外,Animal的每个实例都有一个方法populate(),它使用随机值填充实例的属性.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import random
animals = [ ("Bella", "cow"), ("Spike", "dog"), ("José", "iguana"), ("Tux", "penguin") ]
class Animal (object):
@staticmethod
def populate (*args): return map (lambda x: Animal (*x), animals)
def __init__ (self, name = None, species = None):
def bar (): self.name, self.species = random.choice (animals)
self.name = name
self.species = species
self.populate = bar
def __repr__ (self): return "%s of species %s" % (self.name, self.species)
print Animal.populate ()
print Animal ("Pinky", "mouse")
qux = Animal ()
qux.populate ()
print qux
Run Code Online (Sandbox Code Playgroud)
代码工作正常,但让我怀疑的是print Animal.populate (qux)调用静态populate方法的事实(因此返回了一个列表而没有填充糟糕的qux).显然,我的信念Foo ().bar ()只不过Foo.bar (Foo () )是一个简短的手段,这是错误的.
这为我提出了各种问题:
Foo ().bar ()?Foo.bar (Foo () )?(是的,它必须是同一个名字.)
关于 Foo().bar()、Foo.bar(Foo()) 和 Foo.bar() 之间的区别(作为答案,因为我昨天注册了,还不能发表评论) - 这是因为 Python( <3.0) 的“绑定”和“非绑定”方法的概念 - 它严格要求,除了 @staticmethod 或 @classmethod 之外,方法调用具有与其关联的实例。没有什么比你必须记住的东西更容易解释它的方法了。值得庆幸的是,这在 Python 3 中发生了变化 - “绑定”和“非绑定”方法作为单独事物的概念已经消失,并且 Foo.bar() 对于您的示例来说效果很好。