-
方法相关补充
-
私有化方法:__方法名,存储后变为_类名.__方法名
-
内置特殊方法
-
生命周期方法
-
其他内置方法
-
信息格式化操作:__str__方法(面向用户)、__repr__方法(面向python解释器、开发人员)
class Person: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return "这个人的姓名是%s,年龄是%s"%(self.name,self.age) p1 = Person("sz", 11) print(p1) print(str(p1))
import datetime now = datetime.datetime.now() print(now)# 2021-10-23 11:49:40.357769 print(repr(now))# datetime.datetime(2021, 10, 23, 11, 49, 40, 357769) temp = repr(now) result = eval(temp) print(result)# 2021-10-23 11:49:40.357769
-
调用操作:__call__方法
作用:使得”对象“具备当作函数,来调用的能力
使用:
应用场景:
案例:
class PenFactory: def __init__(self,p_type): self.type = p_type def __call__(self, p_color): print("创建了一个%s类型的画笔,它是%s颜色"%(self.type,p_color)) gangbiF = PenFactory("钢笔") gangbiF("红色") gangbiF("绿色") gangbiF("黄色")
-
索引操作
作用:可以对一个实例对象进行索引操作
步骤:
-
实现三个内置方法
class Person: def __init__(self): self.cache = {} def __setitem__(self, key, value): self.cache[key] = value def __getitem__(self, item): return self.cache[item] def __delitem__(self, key): del self.cache[key] p = Person() p["name"] = "sz" print(p["name"]) del p["name"] print(p.cache)
-
可以以索引的形式操作对象
- 增/改:p[1] = 999、p[“name”] = “sz”
- 查:p[1]、p[“name”]
- 删:del p[1]、del p[“name”]
-
-
切片操作
-
python2
- 实现三个内置方法
- __setspice__:设置某个元素切片时调用
- __getspice__:获取某个元素切片时调用
- __delspice__:删除某个元素切片时调用
- 可以直接按照切片的方式操作对象:p[1,6,2]
- 注意:过期
- 实现三个内置方法
-
python3:统一由“索引操作”进行管理
-
def __setitem__(self,key,value)
-
def __getitem__(self,item)
-
def _delitem_(self,key)
class Person: def __init__(self): self.items = [1,2,3,4,5,6,7,8] def __setitem__(self, key, value): if isinstance(key,slice): self.items[key.start:key.stop:key.step] = value def __getitem__(self, item): print("getitem",item) def __delitem__(self, key): print("delitem",key) p = Person() p[0:4:2] = ["a","b"] print(p.items)
-
-
-
比较操作:
-
作用:可以自定义对象“比较大小、相等、真假”规则
-
步骤:
- 相等:__eq__
- 不相等:_ne_
- 小于:__lt__
- 小于等于:__le__
- 大于:_gt_
- 大于等于:_ge_
class Person: def __init__(self,age,height): self.age = age self.height = height def __eq__(self, other):#等于 return self.age == other.age #如果该方法没实现,则默认为eq结果反着来 def __ne__(self, other):#不等于 return self.age != other.age def __gt__(self, other):#大于 pass def __ge__(self, other):#大于等于 pass def __lt__(self, other):#小于 pass def __le__(self, other):#小于等于 pass p1 = Person(11,111) p2 = Person(11,123) print(p1 == p2)# ==、!=、>、>=、<、<=
-
注意:
- 如果对于反向操作的比较运算符,只定义了其中一种方法,但使用的是另外一种比较运算,那么解释器会采用调换参数的方式调用该方法。
- 但是不支持叠加操作
-
补充:
-
使用装饰器,自动生成“反向”“组合”的方法(略)
-
上下文环境中的布尔值:__bool__
class Person: def __init__(self): self.age = 20 def __bool__(self): return self.age>=18 p = Person() if p: print("成年了")
-
-
-
遍历操作
-
怎样让我们自己创建的对象可以使用for in进行遍历
-
方式一:实现__getitem__方法
class Person: def __init__(self): self.result = 1 def __getitem__(self, item): self.result+=1 if self.result > 6: raise StopIteration("停止遍历") return self.result p = Person() for i in p: print(i)
-
方式二:实现__iter__方法(优先级更高)
class Person: def __init__(self): self.result = 1 def __iter__(self): print("iter") #return iter([1,2,3,5])#如果是返回这个,则无需重写next方法 return self#将自身作为迭代器,则需要重写next方法 def __next__(self): self.result += 1 if self.result >=6: raise StopIteration("停止遍历") return self.result p = Person() for i in p: print(i)
-
-
怎样让我们自己创建的对象可以使用next函数进行访问
-
补充
-
-
描述器
-
概念:可以描述一个属性操作的对象
- 对象
- 属性的操作:增改、删、查
- 描述
-
作用
-
定义
-
定义一:property
#方式一 class Person(object): def __init__(self): self.__age = 18 def get_age(self): return self.__age def set_age(self,value): if value <0: value = 0 self.__age = value def del_age(self): del self.__age age = property(get_age,set_age,del_age) p = Person() print(p.age) p.age = 30 print(p.age) del p.age print(p.age) help(Person) #方式二 class Person(object): def __init__(self): self.__age = 18 @property def age(self): return self.__age @age.setter def age(self,value): self.__age = value @age.deleter def age(self): del self.__age p = Person() print(p.age) p.age = 30 print(p.age) del p.age print(p.age)
-
定义二
class Age: def __get__(self, instance, owner): print("get") def __set__(self, instance, value): print("set") def __delete__(self, instance): print("delete") class Person: age = Age() p = Person() p.age = 11 print(p.age) del p.age
-
-
调用细节
- 使用实例进行调用(可以)
- 使用类进行调用(不能)
- 不能顺利转换的场景:
- 新式类和经典类:新式类中可以生效
- 方法拦截
- 一个实例属性的正常访问顺序
- 实例对象自身的__dict__字典
- 对于类对象的__dict__字典
- 如果有父类,会往上层的__dict__字典中检测
- 如果没有找到,又定义了__getattr__方法,就会调用这个方法
- 而在上述的整个过程当中,是如何将描述器的__get__方法给嵌入到查找机制当中?
- 就是通过这个方式进行实现:
- _getattribute_
- 内部实现模拟:如果实现了描述器方法__get__,就会直接调用;如果没有则按照上面的机制去查找
- 一个实例属性的正常访问顺序
-
注意:描述器和实例属性同名时,操作优先级
-
资料描述器 :get、set
-
非资料描述器:仅实现了get方法
-
资料描述器 > 实例属性 > 非资料描述器
-
装饰器:类实现如下:
#一 class Check: def __init__(self,func): self.f = func def __call__(self, *args, **kwargs): print("登陆验证") self.f() def fashuoshuo(): print("发说说") fashuoshuo1 = Check(fashuoshuo) fashuoshuo1() #二 class Check: def __init__(self,func): self.f = func def __call__(self, *args, **kwargs): print("登陆验证") self.f() @Check def fashuoshuo(): print("发说说") fashuoshuo()
-
-
-
-
-