标签:com 图片 ict 斐波那契 ack except 语言 添加 repr
1.实例只有数据属性,函数属性是属于类的 对于类的函数属性的更改可以立刻反映在实例上 可以用__dict__查看 实例产生只是执行了__init__
2.风湿理论的应用
类似于将函数属性变成数据属性那样去显示
1 class Romm(): 2 def __init__(self,long, width): 3 self.long = long 4 self.width = width 5 self.high = 100 6 7 @property 8 def area(self): 9 area = int(self.long) + int(self.width)+self.high 10 return area 11 12 a1 = Romm(100,200) 13 print(a1.area)
自定义实现 property
a.装饰器 类也可以作为一个装饰器,只需要在定义__init__ 传入适当的参数
1 class LazyProperty(): 2 3 def __init__(self, func): #func 就是需要修饰的函数 4 self.func = func 5 print(self.func)
b.描述符
1 class LazyProperty(): 2 3 def __init__(self, func): 4 self.func = func 5 print(self.func) # self.func就是类Room的方法area 6 7 def __get__(self, instance, owner): 8 print(‘instance is %s‘% instance) #instance 就是实例r1 9 10 res = self.func(instance) #传入self 11 return res 12 13 14 15 16 17 class Room: 18 #area = Lazyproperty(area) #==》就是类中装饰器的效果 等于第16行 19 def __init__(self, name ,width, length): 20 self.name = name 21 self.width = width 22 self.lenth = length 23 24 @LazyProperty #area = LazyProperty(area) #既实现了装饰器还实现了描述符 25 def area(self): 26 return self.width * self.lenth 27 28 r1 = Room(‘zhou‘, 60,60) 29 print(r1.area) #触发get,返回r1.area()
c.自定制property并实现延时计算
1 class LazyProperty(): 2 3 def __init__(self, func): 4 self.func = func 5 print(self.func) # self.func就是类Room的方法area 6 7 def __get__(self, instance, owner): 8 9 print(‘instance is %s‘% instance) #instance 就是实例r1,如果是类调用instance 为None 10 if instance is None: #类调用模仿实际的静态属性 返回LazyProperty类的对象 11 return self 12 res = self.func(instance) #传入self 13 setattr(instance, self.func.__name__, res) #将属性及值加入到实例字典中这样下次调用就会直接在实例字典中寻找,不会重复计算 14 return res #之所以写成非数据描述符是因为他优先级比实例属性低 写入字典之后就不会再去触发该非数据描述符 达到不重复计算的目的 15 16 17 18 19 20 class Room: 21 #area = Lazyproperty(area) #==》就是类中装饰器的效果 等于第16行 22 def __init__(self, name ,width, length): 23 self.name = name 24 self.width = width 25 self.lenth = length 26 27 @LazyProperty #area = LazyProperty(area) #既实现了装饰器还实现了描述符 28 def area(self): 29 return self.width * self.lenth 30 31 r1 = Room(‘zhou‘, 60,60) 32 print(r1.area) #触发get,返回r1.area() 33 34 #print(Room.area) 35 print(r1.__dict__)
与类绑定也是用装饰器来用
1 class Romm(): 2 def __init__(self,long, width): 3 self.long = long 4 self.width = width 5 self.high = 100 6 7 @classmethod 8 def test(cls): 9 print(‘cls‘) 10 print(‘this is classmethod‘) 11 12 print(Romm.test())
自定制@classmethod
自定制@staticmethod
不与实例和类绑定 类的工具包
1 class People(): 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 self.gender = ‘man‘ 6 7 @staticmethod 8 def static_test(a, b): 9 return(a+b) 10 11 def no_test(a, b): 12 return(a+b) 13 14 15 16 p1 = People(‘zhou‘, 3221) 17 print(p1.static_test(1, 2)) #3 18 print(p1.no_test(1, 2)) #会报错,因为实例调用会传入一个self takes 2 positional arguments but 3 were given
1 class School(): 2 def __init__(self, name, address): 3 self.name = name 4 self.address = address 5 6 class Course(): 7 def __init__(self, course_name, price, period, shool): 8 self.course_name = course_name 9 self.price = price 10 self.period = period 11 self.shool = shool 12 13 s1 = School(‘jialidun‘, ‘wuxi‘) 14 s2 = School(‘Boshi‘, ‘beijing‘) 15 s3 = School(‘qinghua‘, ‘shanghai‘) 16 17 menu = { 18 ‘1‘ :s1, 19 ‘2‘ :s2, 20 ‘3‘ :s3 21 } 22 23 while True: 24 msg = """ 25 1:jialidun, wuxi 26 2:Boshi, beijing 27 3:qinghua,shanghai 28 29 """ 30 print(msg) 31 choice = input(‘please choose a school>>>>‘) 32 shool_obj = menu[choice] 33 34 name = input(‘please input lesson name>>>>‘) 35 price = input(‘please input price>>>>>‘) 36 period = input(‘please input period>>>‘) 37 38 c1 = Course(name, price, period, shool_obj) 39 40 print(‘课程%s的学校是%s‘% (c1.course_name, c1.shool.name))
a.在子类代码中父类调用并传入参数‘self‘
1 class Verchile(): 2 def __init__(self, name, speed): 3 self.name = name 4 self.speed = speed 5 6 def run(self): 7 print(‘%s is runing with speed‘ % self.name, self.speed) 8 9 10 class Car(Verchile): 11 def __init__(self, name, speed, note): 12 Verchile.__init__(self,name, speed) #父类来调用该init方法,尤其要传入一个参数self 13 self.note = note 14 15 def run(self): 16 Verchile.run(self) #父类来调用该run方法,尤其要传入一个参数self 17 print(‘note:only for %s‘ % self.note) 18 19 car01 = Car(‘汽车‘, 100, ‘only for people‘) 20 car01.run()
b.使用super()来实现
1 class Verchile(): 2 def __init__(self, name, speed): 3 self.name = name 4 self.speed = speed 5 6 def run(self): 7 print(‘%s is runing with speed‘ % self.name, self.speed) 8 9 10 class Car(Verchile): 11 def __init__(self, name, speed, note): 12 # Verchile.__init__(self,name, speed) #父类来调用该init方法,尤其要传入一个参数self 13 super().__init__(name, speed) #使用super() 或者 super(Verchile, Self) 也可以实现 14 self.note = note 15 16 def run(self): 17 # Verchile.run(self) #父类来调用该run方法,尤其要传入一个参数self 18 super().run() #使用super() 19 print(‘note:only for %s‘ % self.note) 20 21 car01 = Car(‘汽车‘, 100, ‘only for people‘) 22 car01.run()
1 class TypeTest(): 2 def __init__(self,value): 3 self.value = value 4 5 def Count(self): 6 i = 0 7 for item in self.value: 8 i += 1 9 # print(self.value) 10 # print(i) 11 print("%s lenth is %d" % (self.value, i)) 12 13 class Type_str(TypeTest): 14 pass 15 16 class Type_list(TypeTest): 17 pass 18 19 20 str1 = Type_str(‘abc‘) 21 list1 = TypeTest([‘1‘, ‘2‘, ‘3‘, ‘4‘]) 22 23 # str1.Count() 24 # list1.Count() 25 26 def Count(obj): 27 obj.Count() 28 29 Count(str1) # 类似与 len()和 __len__() 30 Count(list1)
1 class People(): 2 Country = ‘China‘ 3 def __init__(self,name): 4 self.name = name 5 6 def eat(self): 7 print(‘%s is now eating‘ % self.name) 8 9 p1 = People(‘zhangsan‘) 10 p1.eat() 11 12 # hasattr 实际是找实例能调用到的属性 注意第二个参数属性要加引号表示字符串 13 14 print(hasattr(p1, ‘Country‘)) #True 15 print(hasattr(p1, ‘name‘)) #True 16 print(p1.__dict__) #{‘name‘: ‘zhangsan‘} 17 18 # getattr 找不到会报错 19 20 print(getattr(p1, ‘name‘)) # zhangsan 21 print(getattr(p1, ‘eat‘)) #bound method People.eat of <__main__.People object at 0x00000000021F3BA8>> 22 getattr(p1, ‘eat‘)() # zhangsan is now eating 基于上一条可以加括号调用 23 print(getattr(p1, ‘smeil‘, ‘Can not find!!!‘)) # 找不到会报错,可以加入第三个参数 给出提示信息 24 25 # setattr 26 27 setattr(p1, ‘name‘, ‘lisi‘) # => p1.name = ‘lisi‘ 28 print(getattr(p1, ‘name‘)) #lisi 29 setattr(p1, ‘age‘, 13) 30 print(p1.__dict__) #{‘name‘: ‘lisi‘, ‘age‘: 13} 31 32 # delattr 33 setattr(p1, ‘age‘, 13) 34 print(p1.__dict__) #{‘name‘: ‘lisi‘, ‘age‘: 13} 35 delattr(p1, ‘age‘) 36 print(p1.__dict__) #{‘name‘: ‘zhangsan‘}
setattr 也可以添加新的函数属性
1 setattr(p1, ‘adder‘, lambda x: x+1) 2 print(p1.adder(1)) 3 print(p1.__dict__) #{‘name‘: ‘lisi‘, ‘age‘: 13, ‘adder‘: <function <lambda> at 0x00000000021D6598>} 函数属性也会显示出来
事先先定义接口,后面实现
import fanshe p2 = fanshe.People(‘lisi‘) print(p2.showname()) if hasattr(p2,‘showage‘): showage = getattr(p2, ‘showage‘) showage() else: print(‘do not has this fuction‘)
1 module = __import__(‘module.m‘) #会运行m里面的代码,但是导入只到module 2 print(module) #<module ‘module‘ from ‘F:\\PythonCharm\\20180610\\module\\__init__.py‘> 3 4 import importlib 5 6 module = importlib.import_module(‘module.m‘) #可以直接到 module.m 7 print(module) #<module ‘module.m‘ from ‘F:\\PythonCharm\\20180610\\module\\m.py‘>
1 class People(): 2 z = 100 3 def __init__(self,x): 4 self.x = x 5 6 #当找不到的时候才会触发 7 def __getattr__(self, item): 8 print(‘__getattr__getattr启动‘) 9 10 #删除时会触发 11 def __delattr__(self, item): 12 print(‘__delattr__delattr启动‘) 13 self.__dict__.pop(item) 14 15 #设置属性值的时候出触发包括初始化的时候 16 def __setattr__(self, key, value): 17 print(‘__setattr__delattr启动‘) 18 #self.key = value #这种写法会进入无限迭代 19 self.__dict__[key] = value #设置属性实际是对字典属性的操作 20 21 p1 = People(10) 22 print(p1.x) #10 23 p1.y #找不到数据属性y __getattr__启动 24 25 del p1.x #__delattr__启动 删除实例数据属性 26 del p1.z #__delattr__启动 删除类数据属性 27 28 p1.a = 100 #__setattr__delattr启动
待补充。。。
1 class Human(): 2 pass 3 4 class People(Human): 5 pass 6 7 p1 = People() 8 9 print(isinstance(p1,People)) #判断是否是类的实例 10 11 print(issubclass(People, Human)) #判断是否是类的子类
调用属性的时候无论找到 找不到都会触发 __getattribute__
当找不到的时候,__getattribute__ 抛出异常,然后__getattr__会执行
__getattr__ 就像是 __getattribute__的小弟,而抛出的 AttributeError 异常就像是他们之间的口令
1 class People(): 2 def __init__(self, name): 3 self.name = name 4 5 def __getattr__(self, item): 6 print(‘this is __getattr__‘) 7 8 def __getattribute__(self, item): 9 print(‘this is __getattribute__‘) 10 raise AttributeError(‘can not find,go to __getattr__‘) 11 12 p1 = People(‘zhangsan‘) 13 #print(p1.name) 14 15 p1.xxxxx 16 p1.name
注意触发的写法
__getitem__ => instance[attribute]
__setitem__ =>instance[attribute] = value
__delitem__ =>del instance[atrribute]
1 class People(): 2 def __init__(self, name): 3 self.name = name 4 5 def __getitem__(self, item): 6 print(item) #=> name 7 print(‘This is __getitem__‘) 8 return self.__dict__[item] 9 10 11 def __setitem__(self, key, value): 12 print(‘This is __setitem__‘) 13 self.__dict__[key] = value 14 15 def __delitem__(self, key): 16 print(‘This is __delitem__‘) 17 self.__dict__.pop(key) 18 19 p1 = People(‘WOW‘) 20 21 22 print(p1[‘name‘]) #触发__getitem__ 输出“WOW” 23 24 p1[‘age‘] = 18 #触发__getitem__ 25 print(p1.__dict__) #{‘name‘: ‘WOW‘, ‘age‘: 18} 可以看出已经成功写入 26 27 del p1[‘age‘] #触发__delitem__ 28 print(p1.__dict__) #{‘name‘: ‘WOW‘, ‘age‘: 18} 可以看出已经成功删除
18.__str__,__repr__, __format__
__str__,__repr__ 都会输出字符串,且__str__不存在的时候,__repr__会代替他的工作
1 class People(): 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6 def __str__(self): 7 return ‘%s\‘ age is %d‘ % (self.name, self.age) 8 9 def __repr__(self): 10 return ‘%s\‘ age is %d,this is from __repr__‘ % (self.name, self.age) 11 12 13 p1 = People(‘Knight‘, 22) 14 print(p1) # print和str会调用__str__方法 当没有重载的时候 <__main__.People object at 0x00000000026B3A90> 15 print(p1) # 当重载之后,会调用__str__ ,输出 Knight‘ age is 22 一个字符串 16 17 print(repr(p1)) # repr或者解释器会调用该方法,输出一个字符串 ‘Knight‘ age is 22,this is from __repr’
a.__slots__ 是hi一个变量,可以是字符串,列表,元组 甚至是可迭代对象 其针对的是实例,
b.优点是可以节约内存,实例的__dict__将会不存在
1 class Foo: 2 __slots__ = (‘name‘,‘age‘) 3 pass 4 5 f = Foo() 6 f.name = ‘zs‘ 7 f.age = 13 8 9 #print(f.__dict__) #报错 AttributeError: ‘Foo‘ object has no attribute ‘__dict__‘ 10 print(f.__slots__) #(‘name‘, ‘age‘)
实现一个迭代器协议:
1 class Foo(): 2 3 def __init__(self, n): 4 self.n = n 5 6 def __iter__(self): 7 return self #返回他自己变成迭代对象 8 9 def __next__(self): 10 if self.n>20: #终止循环的条件 11 raise StopIteration(‘Please Stop‘) #抛出异常,但程序不会崩溃 12 self.n = self.n+1 13 return self.n 14 15 p = Foo(8) 16 for i in p: 17 print(i)
迭代器实现斐波那契数列
引用自百度百科:
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。
1 class Fib: 2 3 def __init__(self): 4 self._a = 1 5 self._b = 1 6 7 def __iter__(self): 8 return self #返回他自己变成迭代对象 9 10 def __next__(self): 11 12 self._a, self._b = self._b,self._a+self._b 13 14 return self._a 15 16 17 18 f = Fib() 19 20 for i in f: 21 if i> 20: 22 break 23 print(‘%s ‘ %i,end=‘‘)
子类无法继承父类的__doc__,因为子类的属性字典里已经有了而且无法删除
22.__module__,__class__
23.__del__
24.__enter__,__exist__
25.__call__
a.描述符本质是一个新式类,且实现了__get__,__set__,__del
b.描述符是用来描述另外一个新式类的且只能写在类属性中,不能写在构造函数中
c.数据描述符 实现了__get__和__set__
d.非数据描述符 没有实现__set__
e.描述符的优先级 类属性>数据描述符>实例属性>非属性描述符>找不到(触发__getattr__)
1 class Type: 2 3 def __get__(self, instance, owner): 4 print(‘this is __get__ start--------->‘) 5 print(‘[self] in __get__ is %s‘ % self) 6 print(‘[instance] is %s‘ % instance) 7 print(‘[owner] is %s‘% owner) 8 print(‘this is __get__ over--------->‘) 9 10 def __set__(self, instance, value): 11 print(‘this is __set__ start--------->‘) 12 print(‘[self]in __set__ is %s‘% self) 13 print(‘[instance] is %s‘% instance) 14 print(‘[value] is %s‘% value) 15 print(‘this is __set__ over--------->‘) 16 17 def __del__(self): 18 pass 19 20 class People: 21 name = Type() #name属性由委托数据描述符Type()代理 22 def __init__(self, name, age): 23 self.name = name 24 self.age = age 25 26 p1 = People(‘a1‘,‘18‘) 27 28 print(p1.__dict__) #{‘age‘: ‘18‘} 因为name是数据描述符,比实例属性优先级高,而且数据描述符我们目前只是实现了打印,的没有实现赋值的时候 name不会再字典里
描述符的应用
类的属性查找赋值删除,需要使用数据描述符 因为它优先级比实例属性要高
1 class Type: 2 3 def __init__(self,key): 4 self.key = key 5 6 7 def __get__(self, instance, owner): 8 print(‘this is __get__‘) 9 return instance.__dict__[self.key] 10 11 def __set__(self, instance, value): 12 print(‘this is __set__‘) 13 instance.__dict__[self.key] = value 14 15 16 def __delete__(self, instance): 17 print(‘this is __delete__‘) 18 instance.__dict__.pop(self.key) 19 #del instance.__dict__[self.key] 这个也可以删除 20 21 22 23 24 25 class People: 26 name = Type(‘name‘) #name属性由委托数据描述符Type()代理 27 def __init__(self, name, age): 28 self.name = name 29 self.age = age 30 31 p1 = People(‘a1‘,‘18‘) 32 33 print(p1.__dict__) #{‘name‘: ‘a1‘, ‘age‘: ‘18‘} 34 35 print(p1.name) #a1 36 37 del p1.name 38 39 print(p1.__dict__) #{‘age‘: ‘18‘}
可以对输入的数据进行限制,因为Python是弱数据类型的编程语言,可以通过描述符的方法对属性进行限制
1 class Type: 2 3 def __init__(self,key,exception_type): 4 self.key = key 5 self.exception_type = exception_type 6 7 8 9 def __get__(self, instance, owner): 10 11 return instance.__dict__[self.key] 12 13 def __set__(self, instance, value): 14 print(‘this is __set__‘) 15 16 if not isinstance(value, self.exception_type): 17 print(‘%s\‘s value is %s and it is not the type: %s‘ %(self.key, value, self.exception_type)) 18 #raise TypeError(‘Expected %s‘ %str(self.exception_type)) 19 else: 20 instance.__dict__[self.key] = value 21 22 23 def __delete__(self, instance): 24 print(‘this is __delete__‘) 25 instance.__dict__.pop(self.key) 26 #del instance.__dict__[self.key] 这个也可以删除 27 28 29 30 31 32 class People: 33 name = Type(‘name‘,str) #name属性由委托数据描述符Type()代理 str不能写成字符串 34 age = Type(‘age‘,int) #int同理 多加一个类型参数 可以处理多种情况避免代码重复 35 def __init__(self, name, age): 36 self.name = name 37 self.age = age 38 39 p1 = People(22, ‘18‘) #name‘s value is 22 and it is not the type: <class ‘str‘> ,age‘s value is 18 and it is not the type: <class ‘int‘> 40 41 print(p1.__dict__) #{}
一切皆对象,装饰器同样适用于类,语法都是一样的
1 def deco(obj): 2 print(‘这是类的装饰器deco‘) 3 return obj 4 @deco 5 class People(): 6 pass 7 8 p1 = People()
通过装饰器给一个类赋值
1 def deco(obj): 2 print(‘这是类的装饰器deco‘) 3 obj.x = 1 4 obj.y = 2 5 obj.z = 3 6 return obj 7 8 @deco # Pepple = deco(People) 9 class People(): 10 pass 11 12 print(People.__dict__)
假如我们有新需求,给多个类赋不同的值呢?
1 def Mul(**kwargs): 2 def deco(obj): 3 print(‘这是类的装饰器deco,对类%s装饰‘ % obj) 4 for key, value in kwargs.items(): 5 setattr(obj, key, value) 6 return obj 7 return deco 8 9 @Mul(x=1,y=2,z=3) #先运行Mul,将参数传递,然后运行 People=deco(People) 10 class People(): 11 pass 12 13 print(People.__dict__) 14 15 @Mul(name=‘zhou‘) 16 class Bar(): 17 pass 18 19 print(Bar.__dict__)
# with open(‘a.txt‘) as f:
# ‘代码块‘
1.要有__enter__和 __exit__方法
2.__enter__的返回值返回给as 后面定义的变量
3.__exist__作为with语句的出口最后执行,且抛出异常中止,吞掉异常with可以正常结束,但异常后面的语句不会继续执行
4.
exc_type 异常类型
exc_val 异常值
exc_tb) 异常 traceback
1 # with open(‘a.txt‘) as f: 2 # ‘代码块‘ 3 4 class Open: 5 def __init__(self, name): 6 self.name = name 7 8 def __enter__(self): 9 print(‘this is __enter__‘) 10 return self 11 12 13 def __exit__(self, exc_type, exc_val, exc_tb): 14 print(exc_type) 15 print(exc_val) 16 print(exc_tb) 17 print(‘this is __exit‘) 18 return True #返回True 可以将异常吃掉,with里面该异常后面的语句不会继续执行,但with 语句会正常结束。后面块的语句也可以正常执行 19 20 21 #__enter__ 的返回值会返回给as 语句,如果是文件则返回文件句柄 22 #__exit__语句运行结束之后 则with语句结束,所以在该语句里可以写自动清理的功能 23 with Open(‘a.txt‘) as f: 24 print(f) 25 print(‘---------->1‘) 26 print(‘---------->2‘) 27 print(‘---------->3‘) 28 print(实施的撒) 29 print(‘---------->4‘) 30 print(‘---------->5‘) 31 print(‘------------Final-----------‘) #即使有异常,但只要有__exit__ 的‘return True‘ 程序会正常结束
标签:com 图片 ict 斐波那契 ack except 语言 添加 repr
原文地址:https://www.cnblogs.com/zh22333/p/9148712.html