python 优先级继承_python面向对象进阶之组合与继承授权及常见内置方法

1、组合

一个类的对象属性封装了另一个类的对象

classSchool:def __init__(self,name,addr):

self.name=name

self.addr=addrclassCourse:def __init__(self, name, price, period, school):

self.name=name

self.price=price

self.period=period

self.school=school

s1=School('复旦大学','上海')

c1=Course('py','100','1',s1)print(c1.name) #py

print(c1.school) #<__main__.school object at>

print(c1.school.name)#复旦大学

2、继承

如果某些方法或者属性是共有的,可以定义为一个父类,定义其他类时继承父类,可以访问父类的属性或者方法

#python多类继承,寻找方法或者init顺序#1、左侧优先 2、一条路到底 3、同一个根时最后执行

classBaseRequest:def __init__(self):print('BaseRequest.init')classRequestHandler(BaseRequest):def __init__(self):print('RequestHandler.init')defserve_forever(self):print('RequestHandler.serve_forever')

self.process_request()defprocess_request(self):print('RequestHandler.process_request')classMinx:#def __init__(self):

#print('minx.init')

defprocess_request(self):print('minx.process_request')classSon(Minx,RequestHandler):passobj=Son()

obj.serve_forever()

#执行结果

RequestHandler.init

RequestHandler.serve_forever

minx.process_request

#注意

self永远指调用该方法的对象,本例中self指obj,obj = Son()实例化时会按照顺序先找到__init方法执行,随后执行obj.serve_forever()时按照顺序找到了RequestHandler中的server_forever方法,该方法中执行了

self.process_request(),此时self是obj,还会从头开始按照顺序寻找process_request方法执行

3、授权

实现授权的关键点就是覆盖__getattr__()方法,在代码中包含一个对getattr()内建函数的调用。特别调用getattr()以得到默认对象属性(数据属性或者方法)并返回它以便访问或调用。

importtimeclassFileHandle:def __init__(self,file,mode='r',encoding='utf-8'):#self.file=file

self.file = open(file, mode, encoding=encoding)

self.mode=mode

self.encoding=encoding#重写write,实现写入内容时加上时间

defwrite(self,line):print('执行write方法')print('------------>', line)

t= time.strftime('%Y-%m-%d %X')

self.file.write('%s %s' %(t, line))#重写覆盖__getattr__

def __getattr__(self, item):print(item)returngetattr(self.file, item)

obj=FileHandle('test')#obj.fil #只有在使用点调用属性且属性不存在的时候才会触发__getattr__ 例如obj.fil obj.wri

print(obj.read) #FileHandle类中没有read方法,会触发__getattr__方法,从self.file对象中获取read 实际获取到的是obj.file对象的read

print(obj.read())

obj1=FileHandle('test','w')

obj1.write('1111111111111111\n')

4、常见内置方法

__str__ :使用print时执行改方法,可以改变对象的字符串显示,执行print()和str()都是调用对象.__str__()classFoo:def __init__(self,name):

self.name=namedef __str__(self):returnself.name

obj=Foo('123')print(obj)

res=str(obj)print(res)#123

123

__call__:对象后面加括号,触发执行。classFoo:def __init__(self):pass

def __call__(self, *args, **kwargs):print('__call__')

obj= Foo() #执行 __init__

obj() #执行 __call__

__module__显示当前操作的对象在那个模块__class__显示当前操作的对象的类是什么print(obj.__module__)print(obj.__class__)

__next__和__iter__实现迭代器协议

classFoo:def __init__(self,x):

self.x=xdef __iter__(self):returnselfdef __next__(self):if self.x >10:raiseStopIteration

self.x+=1

returnself.x

f=Foo(3)for i inf:print(i)#4

5

6

7

8

9

10

11说明:for 循环的原理,是先执行对象的__iter__方法使其变为可迭代对象,然后去调用__next__方法,而且for循环可以自动捕捉异常

5、描述符

描述符定义:定义的类中至少实现了__get__(),__set__(),__delete__()中的一个方法。描述符本质上也是一个类

__get__():调用一个属性时,触发__set__():为一个属性赋值时,触发__delete__():采用del删除属性时,触发

描述符一共有两种:数据描述符和非数据描述符,描述符使用时必须把描述符定义为另一个类的属性

数据描述符:至少实现了__get__()和__set__()

非数据描述符:仅定义了__get__()

属性访问的优先级顺序

优先级有高到底1.类属性2.数据描述符3.实例属性4.非数据描述符5.找不到的属性触发__getattr__()

简单使用及验证

classFoo:def __get__(self, instance, owner):print('执行get')print(instance)print(owner)#未定义__set__时就变为非数据描述符

def __set__(self, instance, value):print('执行set')print(instance)print(value)##instance.__dict__['name'] = value

def __delete__(self, instance):print('执行delete')print(instance)classMy:

name=Foo()#name 被定义为一个描述符

def __init__(self,name):

self.name=namepass

#类属性的优先级高于数据描述符

print(My.__dict__)#此时属性字典中'name': <__main__.foo object at>

My.name='root' #可以看到此时并未触发Foo类中的__set__ 说明是直接操作类的属性字典,通过My.__dict__可以查看。由此可以得出类属性的优先级高于数据描述符

print(My.__dict__)#此时属性字典中'name': 'root'

"""#数据描述符属性高于实例属性

obj=My('root')

print(obj.__dict__)

obj.name='root'#可以看到为实例属性name赋值时触发了Foo类中__set__方法执行了,而且通过obj.__dict__查看实例属性字典中并没有name(因为此时我们的set方法中实际并未操作属性字典),由此可以得出数据描述符属性高于实例属性

print(obj.__dict__)"""

"""#实例属性高于非数据描述符

obj=My('root')

print(obj.name)#获取到是root,且并未触发__get__,由此可知实例属性高于非数据描述符

print(obj.__dict__)#{'name': 'root'}"""

自定制实现property

defdecorate(cls):print('类的装饰器开始运行啦------>')

cls.city='shanghai'

returncls

@decorate#无参:People=decorate(People)

classPeople:def __init__(self,name,age,salary):

self.name=name

self.age=age

self.salary=salary

p1=People('egon',18,3333.3)print(People.__dict__)print(p1.city)

#执行结果

func

这是我们自己定制的静态属性,r1.area实际是要执行r1.area()

instance <__main__.room object at>

owner

1

{'__module__': '__main__', '__init__': , 'area': <__main__.myproperty object at>, '__dict__': , '__weakref__': , '__doc__': None}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值