欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python定制类、枚举类和元类

程序员文章站 2022-06-16 15:13:56
...

定制类 :

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

_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:

后续再增加