【转】python中MethodType的使用解析

本文深入解析了Python中MethodType的功能及使用方式,包括如何将方法绑定到类实例或类的不同场景,展示了不同绑定方式下实例间属性的影响。

原文:python中MethodType的使用解析

MethodType:

用MethodType将方法绑定到类,并不是将这个方法直接写到类内部,而是在内存中创建一个link指向外部的方法,在创建实例的时候这个link也会被复制。


情况一:把方法绑定到某个类的实例上

class Student(object):
    pass

def set_name(self, name):
    self.name = name

s1 = Student()
s2 = Student()
s3 = Student()
#将set_name方法绑定到s1实例上
s1.set_name = MethodType(set_name, s1, Student)
s2.set_name = MethodType(set_name, s2, Student)
s1.set_name('tom')
s2.set_name('tony')
>>> print s1.name, ',', s2.name
tom , tony
>>> print s3.name

Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    print s3.name
AttributeError: 'Student' object has no attribute 'name'

解析:MethodType把方法绑定在类实例上时,每个实例有自己单独的指向区域,互不干扰。


情况二:

(1)将方法绑定在类上(有None参数)

class Student(object):
    pass

def set_name(self, name):
    self.name = name

#将方法绑定在类上(有None参数)
Student.set_name = MethodType(set_name,Student)
s1 = Student()
s2 = Student()
s3 = Student()
s1.set_name('tom')
s2.set_name('tony')
>>> print s1.name, ',', s2.name, ',', s3.name
tom , tony ,

Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    print s1.name, ',', s2.name, ',', s3.name
AttributeError: 'Student' object has no attribute 'name'

解析:MethodType把方法绑定在类上并且有第二个None参数时,这种情况下的表现和情况一类似,通过该类创建的实例会指向各自不同的区域,各个实例之间互不干扰。
(2)将方法绑定在类上(没有None参数)

class Student(object):
    pass

def set_name(self, name):
    self.name = name

#将方法绑定在类上(没有None参数)
Student.set_name = MethodType(set_name,Student)
s1 = Student()
s2 = Student()
s3 = Student()
s1.set_name('tom')
s2.set_name('tony')
>>> print s1.name, ',', s2.name, ',', s3.name
tony , tony , tony

解析:MethodType把方法绑定在类上并且没有第二个None参数时,通过该类创建的实例都会指向相同的区域,导致后面实例的值会覆盖前面实例的值。

<think> 我们正在讨论Python中的self参数。根据用户的问题和提供的引用,用户想了解self在Python中属于什么参数。 根据引用内容,我们可以总结如下: 1. self是Python类的方法中的一个参数,且必须是第一个参数(引用[1]、[2]、[3]、[4])。 2. self代表类的实例(对象)本身,通过它可以访问实例的属性和其他方法(引用[2])。 3. 在调用实例方法时,需要显式传递self参数,Python解释器会自动将调用该方法的实例作为self传入(引用[4])。 4. selfPython的关键字,只是一个约定俗成的名称,实际上可以使用任何其他名称,但强烈建议使用self以保持代码可读性(引用[1])。 因此,self在Python中属于“实例参数”或“对象参数”,它指向类的当前实例。 在Python中,方法分为实例方法、类方法和静态方法。self用于实例方法中,用于绑定到实例对象。 我们可以这样定义: - 实例方法:第一个参数为self(指向实例) - 类方法:使用@classmethod装饰器,第一个参数为cls(指向类) - 静态方法:使用@staticmethod装饰器,没有默认的第一个特殊参数 所以,self是实例方法的一个特殊参数,代表实例本身。 接下来,我们可以这样组织回答: 1. 说明self是什么(属于什么参数)。 2. 解释self的作用。 3. 举例说明。 4. 对比类方法和静态方法。 同时,注意在回答中引用提供的参考内容。 此外,根据系统指令,需要使用LaTeX格式的行内数学表达式(如果有数学内容的话)和独立公式(如果有的话)。虽然本题涉及数学公式,但如果有变量或代码,我们按照要求处理。 最后,生成相关问题。 注意:用户要求使用中文回答。 开始回答: </think> ### Self在Python中的参数类型解析Python中,**`self`属于实例方法的第一个位置参数**,本质是**指向当前类实例的引用参数**。其核心特性如下: #### 1. 参数性质 - **强制位置参数**:在实例方法定义中必须作为第一个形参声明 ```python class MyClass: def instance_method(self, arg1, arg2): # self必须是第一个参数 self.var = arg1 + arg2 ``` - **隐式传递机制**:调用时无需显式传值,解释器自动将实例对象注入该参数[^4] ```python obj = MyClass() obj.instance_method(3, 5) # 实际执行: instance_method(obj, 3, 5) ``` #### 2. 核心作用 - **实例标识符**:提供访问当前对象属性和方法的入口 ```python class Person: def __init__(self, name): self.name = name # 通过self绑定实例属性[^2] def greet(self): print(f"Hello, {self.name}") # 通过self访问实例属性 ``` - **生命周期载体**:维护对象状态(每个实例的`self`指向独立内存空间) #### 3. 与其他参数对比 | 参数类型 | 绑定对象 | 声明位置 | 调用方式 | |----------------|-------------|-----------------|----------------| | `self` | 类实例 | 实例方法首位 | 自动隐式传递 | | `cls` | 类本身 | 类方法首位 | 自动隐式传递 | | 普通位置参数 | 无绑定 | 方法参数列表 | 显式传递 | #### 4. 语法本质 - **非关键字**:`self`仅为约定名称,可替换(但建议)[^1] ```python class Demo: def __init__(custom_self, x): # 合法但推荐 custom_self.x = x ``` - **动态绑定**:运行时确定具体实例,实现面向对象的多态特性: $$ \text{方法调用} \rightarrow \text{MethodType(func, instance)} $$ > 关键结论:`self`是Python实现**面向对象编程的语法基石**,通过隐式传递实例引用,建立方法与对象的绑定关系[^3]。 --- ### 相关问题 1. 为什么类方法(`@classmethod`)需要使用`cls`参数而用`self`? 2. 在继承体系中,`self`参数如何实现多态特性? 3. 静态方法(`@staticmethod`)为什么需`self`参数? 4. 如何理解`self.__class__`与`type(self)`的区别? [^1]: Python self参数约定[引用1] [^2]: 实例方法与属性绑定[引用2] [^3]: 类结构中的参数定义[引用3] [^4]: 调用时的隐式传递机制[引用4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值