Discuss / Python / 疑问

疑问

Topic source

Zack_Chang

#1 Created at ... [Delete] [Delete and Lock User]

为什么给类动态绑定方法只用写Student.set_score = score,而给一个实例动态添加方法非得用MethodType函数呢?

s2.set_age = set_age
s2.set_age(24)
s2.age

显示错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-37-5e9ff37912be> in <module>
----> 1 s2.set_age(24)
      2 s2.age

TypeError: set_age() missing 1 required positional argument: 'age'

但如果写成

s2.set_age(s2, 24)
s2.age

就能正确显示24了。

注意看,是函数

class Student(object):
    pass

# 这里是有两个参数,self是作为一个实例传进来的
# 然后给这个实例加了一个age属性,并且赋值
def set_age(self, age): # 定义一个函数作为实例方法
    self.age = age

看调用

# 测试:
s = Student()
s.set_age=set_age
# s.set_age(24) 这样写的话会缺少一个参数,所以报了缺少参数的异常

# 新建一个实例
s1 = Student()
# 第一个参数传入新建的实例来验证一下,set_age属性和age属性都给了谁
s.set_age(s1, 22)

print(s.set_age)
# 输出 
>>> <function set_age at 0x0000028B1B858AF8> 说明这个方法确实绑定到了实例s上

print(s.age)
# 输出
>>> 'Student' object has no attribute 'age'  说明age并没有绑定到s上

print(s1.set_age)
# 输出 
>>> 'Student' object has no attribute 'set_age' 说明这个方法确实绑定到了实例s1上

print(s1.age)
# 输出
>>> 22  说明age绑定到了s1上



所以说

s.set_age=set_age

只是加了个指向`set_age`的方法,并没有实现绑定。

因为给实例绑定函数,那函数是可以使用实例内部的变量的。

from types import MethodType


class Student(object):
    def __init__(self,name):
        self.name=name


def set_age(self, age): # 定义一个函数作为实例方法
    self.age = age
    self.name='Xa'

# 测试:
s = Student('Ma')
s.set_age = MethodType(set_age, s) # 给实例绑定一个方法
s.set_age(25)

print(s.age)
print(s.name)

# 输出
>>> 25
>>> Xa

武破立法

#3 Created at ... [Delete] [Delete and Lock User]

感谢。。


  • 1

Reply