对象父元素函数的参数

时间:2015-05-05 23:01:01

标签: python

在“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”参数而不是第一种情况呢?

1 个答案:

答案 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

希望能够解释得很清楚。