Day28_property_staticmethod_classmethod用法
一. 上节课复习
- 多态与多态性
二.property
-
什么是property:
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值import math class Circle: def __init__(self,radius): #圆的半径radius self.radius=radius @property def area(self): return math.pi * self.radius**2 #计算面积 @property def perimeter(self): return 2*math.pi*self.radius #计算周长 c=Circle(10) print(c.radius) print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值 print(c.perimeter) #同上 ''' 输出结果: 314.1592653589793 62.83185307179586 '''
-
property的设置、删除
class Foo: def __init__(self,val): self.__NAME=val #将所有的数据属性都隐藏起来 @property def name(self): return self.__NAME #obj.name访问的是self.__NAME(这也是真实值的存放位置) @name.setter def name(self,value): if not isinstance(value,str): #在设定值之前进行类型检查 raise TypeError('%s must be str' %value) self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME @name.deleter def name(self): del self.__NAME f=Foo('egon') print(f.name) # f.name=10 #抛出异常'TypeError: 10 must be str' del f.name print(f.name) #'Foo' object has no attribute '_Foo__NAME'
-
被property装饰的属性会优先于对象的属性被使用,而被property装饰的属性,如sex,分成三种:
class People: def __init__(self,name,SEX): self.name = name self.sex = SEX #设置sex 会调用property下的setter @property def sex(self): print('from property') return self.__sex @sex.setter def sex(self,value): print('from setter') self.__sex = value @sex.deleter def sex(self): print('from deleter') del self.__sex p1 = People('Lex','male') #from setter print(p1.__dict__) #{'name': 'Lex', '_People__sex': 'male'} print(p1.sex) #from property #male del p1.sex #from deleter print(p1.__dict__) #{'name': 'Lex'}
- property
- sex.setter
- sex.deleter
三. staticmethod
- 非绑定方法
在类内部用staticmethod装饰的函数即非绑定方法,就是普通函数,statimethod不与类或对象绑定,谁都可以调用,没有自动传值效果import time class Date: def __init__(self,year,month,day): self.year = year self.month = month self.day = day @staticmethod #相当于给类扩展功能 def now(): #用Date.now()形式去产生实例,该实例用的是当前时间 t = time.localtime() #获取结构化的时间格式 obj = Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回 return obj @staticmethod def tomorrow(): #用Date.tomorrow()形式去产生实例,该用例用的是明天的时间 t = time.localtime(time.time()+86400) obj = Date(t.tm_year,t.tm_mon,t.tm_mday) return obj d1 = Date.now() print(d1.year,d1.month,d1.day) d2 = Date.tomorrow() print(d2.year,d2.month,d2.day) #注意: #1. 如果不加staticmethod:但凡是定义在类的内部,并且没有被任何装饰器装饰过的方法,都是绑定方法,有自动传值的功能 d1.now() #报错,TypeError: now() takes 0 positional arguments but 1 was given #2. 如果增加staticmethod:但凡是定义在类的内部,并且被staticmethod装饰器修饰过的方法,都是解除绑定的方法,实际上就是函数,没有自动传值的功能 d1 = Date(2012,12,12) d_n1 = Date.now() d_n2 = d1.now() 与上面相等 print(d_n1.year,d_n1.month,d_n1.day) print(d_n2.year,d_n2.month,d_n2.day)
四.classmethod
-
classmethod的基本使用
class FOO: def bar(self): pass @classmethod #把一个方法绑定给类:类.绑定到类的方法(),会把类本身当做第一个参数自动传给绑定到类的方法 def test(cls,x): print(cls,x) #拿掉一个类的内存地址后,就可以实例化或者引用类的属性了 f = FOO() print(f.bar) #<bound method FOO.bar of <__main__.FOO object at 0x000000000269B208>> 对象的绑定方法 print(f.test) #<bound method FOO.test of <class '__main__.FOO'>> 类的绑定方法 print(FOO.test) #<bound method FOO.test of <class '__main__.FOO'>> 类的绑定方法 f.test(111) #<class '__main__.FOO'> 111,实例可以调用,但是第一个参数传入的是实例对应的类 FOO.test(111) #<class '__main__.FOO'> 111
-
类中函数不加任何装饰器:为foo2的对象
class foo: def foo1(self): pass class foo2(foo): pass f1 = foo2() print(f1) #<__main__.foo2 object at 0x00000000026C89B0>
-
类中函数增加装饰器staticmethod:为Date的对象,且不会触发__str__
import time class Date: def __init__(self,year,month,day): self.year = year self.month = month self.day = day @staticmethod #相当于给类扩展功能 def now(): #用Date.now()形式去产生实例,该实例用的是当前时间 t = time.localtime() #获取结构化的时间格式 obj = Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回 return obj class EuroDate(Date): def __str__(self): return '<name:%s,age:%s>' % (self.name, self.age) e1 = EuroDate.now() print(e1) #<__main__.Date object at 0x0000000001E8B320>,
-
类中函数增加装饰器classmethod:为EuroDate的对象,触发__str__
import time class Date: def __init__(self,year,month,day): self.year = year self.month = month self.day = day @classmethod def now(cls): t = time.localtime() #获取结构化的时间格式 obj = cls(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回 return obj class EuroDate(Date): def __str__(self): return '<year:%s,mont:%s,day:%s>'%(self.year,self.month,self.day) e1 = EuroDate.now() print(e1) #<year:2017,mont:11,day:19> # #<__main__.Date object at 0x0000000001E8B320>
五. __str__的用法
- __str__定义在类的内部,必须返回一个字符串类型
- 打印由这个类产生的对象时 ,会触发执行
class foo: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '<name:%s,age:%s>'%(self.name,self.age) f1 = foo('lex',18) print(f1) #<name:lex,age:18>