python定制类、枚举类和元类

本文介绍了Python中如何通过重写特殊方法如__str__、__iter__、__next__等来定制类的行为,使类能够更好地适应不同的应用场景。同时探讨了如何利用__getattr__和__call__方法为类提供更丰富的功能。

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

定制类 :

类里面有很多自带的方法,我们可以重写他们

__str__

print一个实例对象时会自动调用__str__方法,输出对象的信息

class student(object):
    def __init__(self,name):
        self.name =name
a =student('Bob')
print(a)

output:

<__main__.student object at 0x000002221CB380B8>

显示的不友好,我们可以在类里重写__str__方法

class student(object):
    def __init__(self,name):
        self.name =name
    def __str__(self):
        return 'student name name %s'% self.name
a =student('Bob')
print(a)

output:

student name name Bob
__iter__ 和 __next__

在类中实现__iter__ 方法后,该方法会返回一个迭代对象,这个迭代对象有个__next__方法,python的for循环会不断调用这个方法,知道达到某个条件的时候才终止

class student(object):
    def __init__(self):
        self.count=0
    def __iter__(self):
        return self
    def __next__(self):
        self.count+=1

        if self.count>100:
            raise  StopIteration
        return ('the number is %s'%self.count)
for n in student():
    print(n)
__getitem__

让实例对象表现的像list一样可以同下标访问元素,那么就要在类中实现__getitem__方法

class fib(object):
    def __getitem__(self, item):
        self.a =0
        self.b =1
        print('has been done')
        for i in range(0,item):
            self.a,self.b =self.b,self.a+self.b
        return self.a
x =fib()
print(x[10])

output:

has been done
55

在使用下标的时候,才会调用这个方法

test:

class fib(object):
    def __getitem__(self, item):
        self.a =0
        self.b =1
        print('has been done')
        for i in range(0,item):
            self.a,self.b =self.b,self.a+self.b
        return self.a
x =fib()

没有输出

getitem实现切片的方法: 重写gettitem方法,判断下标是整数还是一个切片,slice有start和end两个属性

class fib(object):
   def __getitem__(self, item):
       a =0
       b = 1
       if isinstance(item,int):
           for i in range(0,item):
               a,b =b,a+b
           return a
       if isinstance(item,slice):
           start = item.start
           end   = item.stop
           if start ==None:
               start =0
           result =[]
           for i in range(end):
               if i >=start:
                   result.append(a)
               a,b =b,a+b
           return result
a =fib()
print(a[1:10])
__getattr__

当调用实例对象不存在的属性时,会自动调用该方法,返回相应的值(前提是类里面写了这个方法)

test1:

class student(object):
    def __init__(self,name):
        self.name =name
a =student('bob')
print(a.score)
print(a.sex)

output:

Traceback (most recent call last):
  File "E:/pythoncode/python_study/model/personclass.py", line 10, in <module>
    print(a.score)
AttributeError: 'student' object has no attribute 'score'

test2:

class student(object):
    def __init__(self,name):
        self.name =name
    def __getattr__(self, item):
        if item =='score':
            return 99
        if item =='sex':
            return 'male'
a =student('bob')
print(a.score)
print(a.sex)

output

99
male

注意:只有在没有找到属性的情况下才会调用getattr方法,否则返回的是已存在的属性的值

__call__

直接调用实例就能产生结果

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

    def __call__(self):
        print('My name is %s.' % self.name)

>>> s = Student('Michael')
>>> s() # self参数不要传入
My name is Michael.

通过callable()函数,我们就可以判断一个对象是否是“可调用”对象。

枚举类

定义:定义枚举要导入enum模块,枚举定义用class关键字,继承Enum类。

from enum import Enum
class color(Enum):
    red =1
    orange =2

定义了颜色color的枚举,一共有两个成员,分别是color.red 、color.orange(注意是color.red而不是red)。每一个成员都有自己的名称和值,color的名称是red,值是1。每个成员的数据类型就是它所属的枚举。

使用:

  1. 通过成员值来获取成员(color(2))

  2. 通过成员名称来获取成员(color[‘red’])

  3. 通过成员来获取成员名和成员值(a =color(1) ,a.name,a.value)

    from enum import Enum
    class color(Enum):
       red ='a'
       orange =2
    print(color.red)
    print(color['red'].value)
    print(color.red.name)

迭代:

(1)

for color in color:
#输出所有的成员

(2)

for color in Color.__members__.items():

输出所有(成员名,\<成员,成员值>)

元类

type:

通常创建类的方法都是创建一个class,然后在class里面写一些可以调用的方法。这属于静态创建的方法,也就是在创建实例之前已经创建了类。而用type函数可以动态的创建一个类,type()函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过type()函数创建出Dancer类,而无需通过class Dancer(object)...的定义:

使用方法:type(类名,由父类名称组成的元组(针对继承的情况,可以为空),包含属性(或者方法)的字典(名称和值))

def sing(self):
    print('sing a song')
def wirte(self):
    print('write a poem')
person = type('person',(),{'s':sing,'w':wirte})

a =person()#此时才会创建类,之前type仅仅是定义
a.s()
a.w()

注意,如果字典里的属性或者方法的键都要用字符串的形式表示(加引号)

metaclass:

后续再增加

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值