在“Dog”类中,如果我初始化为
self.print_func = print_func
如下所示
class Pet(object):
def __init__(self, name, print_func):
self.name = name
self.print_func = print_func
class Dog(Pet):
def __init__(self, name, print_func):
Pet.name = name
self.print_func = print_func
def print_name(self):
self.print_func(self.name)
def print_string(str):
print str
当我做的时候
j.print_name()
一切都很好。
但如果我将Dog class初始化为
Pet.print_func = print_fun
即,
class Dog(Pet):
def __init__(self, name, print_func):
Pet.name = name
Pet.print_func = print_func
def print_name(self):
self.print_func(self.name)
当我做的时候
j.print_name()
我收到此错误
TypeError: print_string() takes exactly 1 argument (2 given)
那么为什么在第二种情况下调用self.print_func会传递“self”参数而不是第一种情况呢?
答案 0 :(得分:3)
这是因为在self
的情况下,你创建了所谓的未绑定函数,在第二种情况下,你创建了绑定函数。绑定函数有效地转换为Dog.print_func(self, self.name)
。
绑定方法在某种意义上有点特殊,它们总是需要self参数而函数则不需要。它们也不存在于__dict__
实例中 - 这正是发生的事情:您没有将其分配给self.__dict__
,而是分配给Pet.__dict__
,因此self
分配给它隐式。
换句话说,设置Pet.print_func
会创建一个方法,而self.print_func
会创建一个函数。
原因是,您没有调用Pet
构造函数 - Pet.print_func
修改父方法列表。小修改使这更清楚:
class Dog(Pet):
def __init__(self, name, print_func):
Pet.name = name
super(Dog, self).print_func = print_func
输出
AttributeError: 'super' object has no attribute 'print_func'
属性(或方法)甚至不存在!但是,如果构造函数被调用...
class Dog(Pet):
def __init__(self, name, print_func):
super(Dog, self).__init__(name, print_func)
您将再次分配给某个功能。输出(给定名称='测试'):
test
进一步探索,行为变得更加具有预测性。可以这样总结:如果向类添加属性,则将其视为方法。向实例添加属性会将其作为函数(或本地属性)。进一步的例子
class Dog(Pet):
def __init__(self, name, print_func):
Pet.name = name
super(Dog, self).__dict__['print_func'] = print_func
输出(给定名称='测试')
test
希望能够解释得很清楚。