在 Python 中,成员方法是指定义在类中的函数,用于操作类的实例对象。成员方法通过第一个参数通常命名为 self
,用来表示调用该方法的实例对象本身。通过成员方法,可以实现类的行为和功能。
成员方法的定义
在类中定义成员方法和定义函数基本一样(原理和运行机制一样),但还是有点不同(形式上有不同)
基本语法:
def 方法名(self,形参列表):方法体
注意:
- 在方法定义的参数列表中,有一个self
- self是定义成员方法时需要写上的(若不需要self这个参数,可以使用@staticmethod方法使得成员方法变为静态方法)
- self表示当前对象本身( 简单地说,哪个对象调用,self就代表哪个对象 )
- 当我们通过对象调用方法时,self会隐式的传入
- 在方法内部,需要使用self,才能访问到成员变量
举例:
class Person:def __init__(self, name, age):self.name = nameself.age = agedef display_info(self):print(f"Name: {self.name}, Age: {self.age}")# 创建 Person 类的实例对象
person1 = Person("Alice", 30)# 调用成员方法 display_info
person1.display_info()
在上面的代码中,display_info
是 Person 类的一个成员方法,用来显示该类的实例对象的信息。通过 person1.display_info()
调用该方法,输出该实例对象的姓名和年龄信息。
@staticmethod 方法的使用
将方法转换为静态方法,静态方法不会接收隐式的第一个参数。要声明一个静态方法,请使用此语法。
class C:@staticmethoddef f(arg1, arg2, argN):....
@staticmethod这样的形式称为函数的decorator。
静态方法既可以由类中调用( 如C.f( ) ),也可以由实例中调用( 如C(),f() )。此外,还可以作为普通的函数进行调用(如 f() )。
像所有装饰器一样,也可以像常规函数一样调用staticmethod,并对其结果执行某些操作。比如某些情况下需要从类主体引用函数并且您希望避免自动转换为实例方法。对于这些情况,请使用此语法:
def regular_function():...
class C:method = staticmethod(regular_function)
举例:
class Dog:name = "藏獒"age = 2# 普通方法def info(self, name):print(f"name信息->{name}")# 静态方法@staticmethod# 通过@staticmethod可以将方法转为静态方法# 如果是一个静态方法,可以不带self参数# 静态方法调用形式有变化def ok():print("ok()...")dog = Dog() # 实例化
dog.info("德牧")# 调用静态方法
# 方式1:通过对象调用
dog.ok()
# 方式2:通过类名调用
Dog.ok()
运行结果:
name信息->德牧
ok()...
ok()...
创建一个Dog类,该类中有一个普通方法 info(self, name) ,一个静态方法 ok(),如果我们将@staticmethod这行注释掉,那么静态方法ok() 就会报错,给出错误原因是,该方法必须有第一个参数,通常被叫做为self。
如果我们不希望有这个self参数,那我们将@staticmethod这行加上即可。
self参数释义
3. self表示当前对象本身( 简单地说,哪个对象调用,self就代表哪个对象 )
class Dog:name = "藏獒"age = 2def hi(self):print(f"hi self:{id(self)}")# self表示当前对象本身
# 创建对象dog2
dog2 = Dog()
print(f"dog2:{id(dog2)}")
dog2.hi()# 创建对象dog3
dog3 = Dog()
print(f"dog3:{id(dog3)}")
dog3.hi()
运行结果:
dog2:1727907491208
hi self:1727907491208
dog3:1727907491400
hi self:1727907491400
注:输出结果不唯一。
举一个通俗易懂的例子来说明self表示当前对象本身这句话:
假设有三个人,张三、李四和王五,他们三个人都说了同一句话,这句话的内容是,我的爸爸,当张三说这句话的时候,则 “我的” 指的是张三,当李四说这句话的时候,则 “我的” 指的是李四,当王五说这句话的时候,则 “我的” 指的是王五。
在上面这个例子中,张三、李四、王五可以看作是由类实例化出来的对象,而 “我的” 可以看作是self参数。
5. 在成员方法内部,需要使用self,才能访问到成员变量和成员方法
先看一段代码,并分析输出的信息是什么?
class Cat:name = "波斯猫"age = 2def info(self, name):print(f"name信息:{name}")cat = Cat()
cat.info("加菲猫")
输出结果:
name信息:加菲猫
问题分析:如果我们希望在成员方法内部,访问对象的属性/成员变量,怎么办?
答案:使用self
class Dog:name = "藏獒"age = 2def eat(self):print(f"{self.name}饿了...")def cry(self, name):print(f"{name} is crying")print(f"{self.name} is crying")self.eat()# eat() # 不能直接调用dog = Dog()
dog.cry("金毛")
输出结果:
金毛 is crying
藏獒 is crying
藏獒饿了...
练习题
定义Person类,里面有name、age属性,并提供compare_to 比较方法,用于判断是否和另一个人相等,名字和年龄都一样,就返回True,否则返回False。
代码如下:
class Person:name = Noneage = Nonedef compare_to(self, other):# 名字和年龄都一样,就返回True,否则返回Falsereturn self.name == other.name and self.age == other.agep1 = Person()
p1.name = "jack"
p1.age = 2p2 = Person()
p2.name = "tim"
p2.age = 2print(p1.compare_to(p2)) # False
我们创建了一个Person类,该类中有两个属性(成员变量)和一个方法(成员方法),两个属性分别为name 、age,一个方法为compare_to。
随后实例化两个对象p1、p2,p1的name属性为 “jack” ,age属性为2,p2的name属性为“tim”,age属性为2。
最后p1调用成员方法compare_to,传入的参数为self 和p2对象,由于self参数可以隐式传入,故只需写p2即可。
由于p1的name属性为jack,p2的name属性为tim,两者不相等,故程序最终输出False。若将p1的name属性改为tim或将p2的name属性改为jack,那么程序会输出True。