类和对象5:绑定和静态、类、抽象方法

本文详细介绍了Python中的静态方法、类方法、抽象方法及其绑定机制。静态方法不依赖实例或类,通过类名调用,不接收self参数。类方法通过@classmethod修饰,接收cls参数,可用于工厂方法和调用静态方法。抽象方法是父类未实现的方法,子类必须实现。方法绑定涉及实例方法、类方法和静态方法的调用方式,以及变量的类与实例绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 静态方法

2. 类方法

3. 抽象方法

4. 绑定

4.1 方法的绑定

4.2 变量的绑定


1. 静态方法

​ 所谓静态方法,即类中不需要与类对象、实例对象绑定的功能,采用 @staticmethod 修饰器修饰,没有 cls 和 self 参数的方法;

静态方法没有 cls、self 参数,因此静态方法中不能调用类中实例变量、实例方法、类方法,但可以通过“类名.静态变量名”、“类名.静态方法”的方式调用类中的静态变量和静态方法;

静态方法同时支持被“类名.静态方法”、“实例名.静态方法”方式调用,参见类和对象:绑定 ;

静态方法调用实例变量、实例方法错误示例如下:

#创建类
class Teststaticmethod1:
    def __init__(self, name):
        self.name = name

    def hello(self):
        print('Hello!')

#创建调用实例变量的静态方法
    @staticmethod
    def showinfo1():
        print(f'展示信息:{self.name}')
    @staticmethod
    def showinfo2():
        print(f'展示信息:{name}')
    @staticmethod
    def showinfo3():
        print(f'展示信息:{Teststaticmethod1.name}')

#创建调用实例方法的静态方法
    @staticmethod
    def sayhello1():
        hello()
    @staticmethod
    def sayhello2():
        Teststaticmethod1.hello()

#调用实例变量失败
Teststaticmethod1.showinfo1()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 10, in showinfo1
NameError: name 'self' is not defined

Teststaticmethod1.showinfo2()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 13, in showinfo2
NameError: name 'name' is not defined

Teststaticmethod1.showinfo3()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 16, in showinfo3
AttributeError: type object 'Teststaticmethod1' has no attribute 'name'

#调用实例方法失败
Teststaticmethod1.sayhello1()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 20, in sayhello1
NameError: name 'hello' is not defined

Teststaticmethod1.sayhello2()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 23, in sayhello2
TypeError: hello() missing 1 required positional argument: 'self'

静态方法调用静态变量、静态方法,以及被类对象、实例对象调用示例如下:

#创建类
class Teststaticmethod2:
    name = 'Teststaticmethod'

    @staticmethod
    def hello():
        print('Hello!')

#静态方法中调用静态变量、静态方法
    @staticmethod
    def sayhello():
        print(f'{Teststaticmethod2.name} say:')
        Teststaticmethod2.hello()

#类对象调用静态方法        
Teststaticmethod2.sayhello()
Teststaticmethod say:
Hello!

#实例对象调用静态方法
testx = Teststaticmethod2()
testx.sayhello()
Teststaticmethod say:
Hello!

2. 类方法

类方法由类调用,采用 @classmethod 装饰,至少传入一个 cls 参数(代指类本身,类似 self 参数);

执行类方法时,自动将调用该方法的类对象或实例对象,赋值给cls;

类方法同时支持被“类名.类方法”、“实例名.类方法”方式调用,参见类和对象:绑定 ;

类方法通常应用于如下两种情况:

  1. 工厂方法,需要传入类对象,以便在类中创建类的实例对象,完成一些实例对象的预处理工作。
  2. 调用静态方法时,使用 “cls.静态方法名”的方式调用,cls 替代了类名,便于后续维护修改、复用代码时,完美继承新类的各种继承、属性和方法。
#-----------工厂方法--------------------------------------
#创建类
class Testclassmethod1:
    def __init__(self, var_a, var_b):
        self.var_a = var_a
        self.var_b = var_b

#定义类方法,可以创建并返回类的实例
    @classmethod
    def newobject(cls, var_a, var_b):
        return cls(var_a, var_b)

#调用类方法,创建实例对象成功
testfactory = Testclassmethod1('test','factory')
x1 = testfactory.newobject('new','1')
x1.var_a
'new'
x1.var_b
'1'

#-----------调用静态方法--------------------------------------
#创建类
class Testclassmethod2:

#供调用的静态方法
    @staticmethod
    def showinfo(info):
        print(f'展示信息:{info}')

#定义类方法,调用静态方法使用“cls.静态方法名”
    @classmethod
    def newinfo(cls, info):
        newinfo = f'前四字节缩略【{info[:4]}】'
        cls.showinfo(newinfo)
#定义等价上述类方法的静态方法,调用静态方法使用“类名.静态方法名”
    @staticmethod
    def newinfo2(info):
        newinfo = f'前四字节缩略【{info[:4]}】'
        Testclassmethod2.showinfo(newinfo)

#验证静态方法和类方法执行效果
Testclassmethod2.showinfo('0123456789')
展示信息:0123456789
Testclassmethod2.newinfo('0123456789')
展示信息:前四字节缩略【0123】
Testclassmethod2.newinfo2('0123456789')
展示信息:前四字节缩略【0123】

3. 抽象方法

Python 中的抽象方法是父类中一个没有实现的方法;

带有抽象方法的父类不可以实例化,继承该父类的子类必须实现该抽象方法,子类才可以创建实例对象;

为确保带有抽象方法的类不可实例化,可以在抽象方法中添加 raise 语句报错;

但工程师在编写子类时仍可能忘记重新实现抽象方法,直到调用抽象方法时才发现报错,为预防这种情况,可以在抽象方法前添加 abc 模块的 @abstractmethod 装饰器,让子类在编码定义时即发现该问题;

#使用raise语句,提示抽象方法
class Testbase1:

    def sayhello(self):
        raise OSError('抽象方法未定义!')

class Testderived1(Testbase1):
     pass

#调用抽象方式时报错
testx = Testderived1()
testx.sayhello()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 4, in sayhello
OSError: 抽象方法未定义!

#使用 @abc.abstractmethod 装饰符,提示抽象方法
import abc
class Testbase2(metaclass = abc.ABCMeta):

    @abc.abstractmethod
    def sayhello(self):
        pass

class Testderived2(Testbase1):
     pass

#创建实例对象时报错
testy = Testderived2()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: Can't instantiate abstract class Testderived2 with abstract method sayhello

#子类实现抽象方法后,可以正常创建实例,并调用方法
class Testderived3(Testbase2):
     def sayhello(self):
         print('hello')
         
testz = Testderived3()
testz.sayhello()
hello

4. 绑定

类中定义的变量和方法,与实例对象、类对象的对应关系,可以称之为绑定

4.1 方法的绑定

Python 中类的方法通常通过 self 参数传入实例对象后,才能被调用;

类中方法的绑定通常有如下几种情况:

  • 不带 self 参数的方法,本质上是一种没有修饰符的静态方法,只能类对象直接调用,实例对象无法调用;
  • 绑定实例对象的普通实例方法,方法通过 self 参数指向实例对象,类对象调用则报错
  • 绑定类对象的类方法,方法通过 cls 参数指向类对象,实例对象和类对象都可以调用,实例对象实际上通过类对象进行的调用;
  • 不绑定的静态方法,没有 self 参数,实例对象和类对象都可以调用;
#创建类
class Test:

#不带 self 参数的方法
    def testFun1():
        print('Hi!')
#实例方法,带 self 参数
    def testFun2(self):
        print('Come on!')
#类方法
    @classmethod
    def testFun3(cls):
        print('Let\'s go!')
#静态方法
    @staticmethod
    def testFun4():
        print('Bye!')

#创建类的实例对象      
test = Test()

#不带 self 参数的方法
#类对象可以调用;实例对象调用,报错
Test.testFun1()
Hi!
test.testFun1()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: testFun1() takes 0 positional arguments but 1 was given

#实例方法
#类对象直接调用,报错;实例对象调用后绑定成功,可以调用
Test.testFun2()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: testFun2() missing 1 required positional argument: 'self'
test.testFun2()
Come on!

#类方法
#类对象和实例对象都可以正常调用
Test.testFun3()
Let's go!
test.testFun3()
Let's go!

#静态方法
#类对象和实例对象都可以正常调用
Test.testFun4()
Bye!
test.testFun4()
Bye!

4.2 变量的绑定

Python 中也存在静态变量和实例变量,静态变量即类中直接赋值的变量,实例变量则是实例方法中以 self. 开头赋值的变量;

静态变量可以直接通过类对象的 __dict__ 属性查询,实例变量则需要创建实例并赋值后在实例对象的 __dict__ 属性中查询;

实例对象中对静态变量重新赋值,则在实例对象中重新创建一个与静态变量同名的实例变量,分别在实例对象和类对象中可以查询得到两个变量不同的值。

#创建类
class TestVar():
#静态变量
    staticvar = 'Hi!'
#初始化实例变量
    def __init__(self, name):
        self.name = name
#实例变量
    def setvar(self,vara,varb):
        self.vara = vara
        self.varb = varb
#调用实例变量的方法
    def showinfo(self):
        print(f'{self.name}:{self.vara},{self.varb}')

#创建实例对象       
testvar = TestVar('TEST')

#类对象 __dict__ 属性,可见静态变量
TestVar.__dict__
mappingproxy({'__module__': '__main__', 'staticvar': 'Hi!', '__init__': <function TestVar.__init__ at 0x000001BEC83D6E50>, 'setvar': <function TestVar.setvar at 0x000001BEC83D6CA0>, 'showinfo': <function TestVar.showinfo at 0x000001BEC83D6DC0>, '__dict__': <attribute '__dict__' of 'TestVar' objects>, '__weakref__': <attribute '__weakref__' of 'TestVar' objects>, '__doc__': None})
#类对象无法调用实例变量
TestVar.name
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: type object 'TestVar' has no attribute 'name'

#实例对象 __dict__ 属性,可见初始化时已创建的实例变量
testvar.__dict__
{'name': 'TEST'}
#实例对象可以调用静态变量、实例变量
testvar.staticvar
'Hi!'
testvar.name
'TEST'
#尚未创建的实例变量不能调用
testvar.vara
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'TestVar' object has no attribute 'vara'

#调用函数赋值创建实例变量
testvar.setvar('Aa','Bb')
#实例对象 __dict__ 属性,可见所有已创建的实例变量
testvar.__dict__
{'name': 'TEST', 'vara': 'Aa', 'varb': 'Bb'}
#使用方法调用实例变量正常执行
testvar.showinfo()
TEST:Aa,Bb

#实例对象,重新赋值静态变量
testvar.staticvar = 'Hello!'
#实例对象中,可见新的与之前静态变量同名的实例变量
testvar.__dict__
{'name': 'TEST', 'vara': 'Aa', 'varb': 'Bb', 'staticvar': 'Hello!'}
#类对象中,原静态变量不变
TestVar.__dict__
mappingproxy({'__module__': '__main__', 'staticvar': 'Hi!', '__init__': <function TestVar.__init__ at 0x000001BEC83D6E50>, 'setvar': <function TestVar.setvar at 0x000001BEC83D6CA0>, 'showinfo': <function TestVar.showinfo at 0x000001BEC83D6DC0>, '__dict__': <attribute '__dict__' of 'TestVar' objects>, '__weakref__': <attribute '__weakref__' of 'TestVar' objects>, '__doc__': None})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燃烧的火鸟啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值