对于类体中定义的实例方法,Python会自动绑定方法的第一个参数(通常建议将参数命名为self),该参数始终指向调用该方法的对象。根据第一个参数出现的位置,绑定到第一个参数的对象略有不同:
在构造函数中引用构造函数正在初始化的对象。
在普通实例方法中引用调用该方法的对象。
由于实例方法(包括构造函数)的第一个self参数是自动绑定的,所以程序在调用普通的实例方法和构造函数时不需要为第一个参数传值。
self参数(自动绑定的第一个参数)用来指代当前方法的调用者,比如前面介绍的构造函数中通过self给对象添加实例变量。你还可以从实例方法中访问该类的另一个实例方法或变量。假设定义了一个 Dog 类,这个 Dog 对象的 run() 方法需要调用它的 jump() 方法。在这种情况下,self参数可以作为jump()方法的调用者。
方法的第一个参数所代表的对象是不确定的,但它的类型是确定的,即它所代表的只能是当前类的一个实例;只有当方法被调用时,它所代表的对象才确定谁在调用这个方法,方法的第一个参数代表谁。
例如定义如下 Dog 类:
class Dog:
# 定义一个jump()方法
def jump(self):
print("正在执行jump方法")
# 定义一个run()方法,run()方法需要借助jump()方法
def run(self):
# 使用self参数引用调用run()方法的对象
self.jump()
print("正在执行run方法")
上面代码的run()方法中的self代表方法的调用者:谁在调用run()方法,那么self就代表了谁。所以这个方法说:当Dog对象调用run()方法时,run()方法需要依赖自己的jump()方法。
当 Python 对象的一个方法调用另一个方法时,不可以省略 self。也就是说,将上面的 run()方法改为如下形式是不正确的:
# 定义一个run()方法,run()方法需要借助jump()方法
def run():
#省略self,下面代码会报错
self.jump()
print("正在执行run方法")
此外,在构造方法中,self 参数(第一个参数)代表该构造方法正在初始化的对象。例如如下代码:
class InConstructor :
def __init__(self) :
# 在构造方法里定义一个foo变量(局部变量)
foo = 0
# 使用self代表该构造方法正在初始化的对象
# 下面的代码将会把该构造方法正在初始化的对象的foo实例变量设为6
self.foo = 6
# 所有使用InConstructor创建的对象的foo实例变量将被设为6
print(InConstructor().foo) # 输出6
在 InConstructor 的构造函数中,self 参数始终引用构造函数正在初始化的对象。程序将被初始化的 InConstructor 对象的 foo 实例变量设置为 6,也就是说构造函数返回的所有对象的 foo 实例变量都等于 6。
需要注意的是,自动绑定的self参数不依赖于具体的调用方式。无论是方法调用还是函数调用执行,self参数也可以自动绑定。例如下面的程序:
class User:
def test(self):
print('self参数: ', self)
u = User()
# 以方法形式调用test()方法
u.test() # <__main__.User object at 0x00000000021F8240>
# 将User对象的test方法赋值给foo变量
foo = u.test
# 通过foo变量(函数形式)调用test()方法。
foo() # <__main__.User object at 0x00000000021F8240>
上面程序中的第五行代码以方法的形式调用了User对象的test()方法。这时候方法调用者当然会自动绑定到方法的第一个参数(自身参数);程序中的第11行代码是一个函数的形式。调用User对象的test()方法时,此时似乎没有调用者,但程序还是会将实际调用者绑定到方法的第一个参数,所以输出结果完全一样。
当self参数作为对象的默认引用时,程序可以像访问普通变量一样访问self参数,甚至可以将self参数当作实例方法的返回值。请参阅下面的程序:
class ReturnSelf :
def grow(self):
if hasattr(self, 'age'):
self.age += 1
else:
self.age = 1
# return self返回调用该方法的对象
return self
rs = ReturnSelf()
# 可以连续调用同一个方法
rs.grow().grow().grow()
print("rs的age属性值是:", rs.age)
从上面的程序可以看出,如果在一个方法中使用self参数作为返回值,可以连续多次调用同一个方法,从而使代码更加简洁。但是,这种使用self参数作为返回值的方法可能会导致实际含义的歧义。比如上面的grow方法用来表示对象的增长,即age属性的值加1,实际上应该没有返回值。
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 如何在python中使用next函数?09/07
- ♥ Python文件读写——理论知识09/25
- ♥ python中的@是什么意思09/15
- ♥ Python黑魔法之属性装饰器详解12/02
- ♥ python如何判断none11/11
- ♥ python如何获取整个页面?11/13
内容反馈