博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python的魔法方法 .
阅读量:7031 次
发布时间:2019-06-28

本文共 5468 字,大约阅读时间需要 18 分钟。

基本行为和属性

__init__(self[,....])构造函数 . 在实例化对象的时候会自动运行

__del__(self)析构函数 . 在对象被回收机制回收的时候会被调用

__str__(self)输出函数 . 在实例对象请求输出的时候会被调用.

__repr__(self). 当直接调用实例对象的时候会被调用

__new__(cls,[,...]). 她的第一个参数是这个类 , 其他的参数被直接传送到 __init__ . 并且__new__是一个对象实例化的时候所调用的第一个方法(所以可以在这里做点手脚) , 

__bool__(self)  定义当被bool类 调用的时候 应当返回的值

__len__(self) 定义单被len调用的时候的行为.

__hash__(self) 定义当被hash 调用的时候返回的函数 . 

__getattr__ (self,name)定义当用户师徒访问一个不存在的属性时 所执行的行为 . 

__getattribute__(self,name)定义当该属性被访问时的行为

__setattribute__ (self,name,value)定义一个属性被设置时的行为 .

__delattr__(self,name)定义一个属性被删除时的行为

__dir__(self) 定义dir被调用时的行为.

__get__(self,instance,owner) 定义当描述符 被取得时的行为

__set__(self,instance,owner)定义当描述符的值被改变是的行为.

__delete__(self,instance) 定义当描述符被删除时的行为

比较操作符,算术运算符,反运算,增量运算,一元操作,类型转换,上下文管理,容器类型.

 

详见

当属性的名称和方法的名称一样的时候 , 属性的名称会自动覆盖方法的名称  , 所以属性和方法的名称影噶尽量分开 .

1 import time as t 2 import sys 3  4 class MyTimer(): 5     def __init__(self):   # 上去先设置 各种属性防止 使用不当出错 .  6         self.unit=['年','月','日','小时','分钟','秒'] 7         self.prompt='未开始计时.' 8         self.lasted=[] 9         self.begin=010         self.end=011     12     def __str__(self):13         print('我被调用了 .')14         return self.prompt15 16     __repr__=__str__17 18     def start(self):19         self.begin=t.localtime()20         print('开始计时')21 22     def stop(self):23         if not self.begin:24             print("请先开始调用 start")25         else:26             self.end=t.localtime()27             self._calc()28             print('计时结束')29 30     def _calc(self):31         self.lasted=[]32         self.prompt='总共运行了'33         for index in range(6):34             self.lasted.append(self.end[index]-self.begin[index])35             if self.lasted[index]:36                 self.prompt+=str(self.lasted[index])+self.unit[index]

 

1 Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32 2 Type "copyright", "credits" or "license()" for more information. 3 >>>  4 =============== RESTART: C:/Users/Administrator/Desktop/new.py =============== 5 >>> t1=MyTimer() 6 >>> t1 7 我被调用了 . 8 未开始计时. 9 >>> t110 我被调用了 .11 未开始计时.12 >>> t1.Stop()13 请先开始调用 start14 >>> t1.Start()15 开始计时16 >>> t1.Stop()17 计时结束18 >>> t119 我被调用了 .20 总共运行了5秒21 >>> print(t1)22 我被调用了 .23 总共运行了5秒24 >>>

 魔法方法的坑 , 和常见的躲坑方法 . 

1 # 这是一个 求面积的程序( 很显然有坑 ) , 如果属性名定义为 square的话 就默认 width=height 2 class Rectangle: 3     def __init__(self,width=0,height=0): 4         self.width=width 5         self.height=height 6  7     def __setattr__(self,name,value): 8         if name=='suqare': 9             self.width=valuc10             self,height=value11         else:12             #super().__setattr__(name,value)13             self.name=value             #如果程序是这样的话实例化对象的时候会出现无限递归  为啥呢?14             15     def GetArea(self):              # 在 最初的 init 那里开始对一个不存在的属性进行赋值 然后就调用了 setattr  调用 setattr的时候 又有 对 该属性(不存在.)进行赋值 然后就递归了.16         return self.width*self.height   # 解决的办法就是 在出错的地方使用官方提供的 方法  super().__setattr__(name,value)
1 >>> c1=Rectangle() 2 Traceback (most recent call last): 3   File "
", line 1, in
4 c1=Rectangle() 5 File "C:\Users\Administrator\Desktop\new.py", line 3, in __init__ 6 self.width=width 7 File "C:\Users\Administrator\Desktop\new.py", line 12, in __setattr__ 8 self.name=value #如果程序是这样的话实例化对象的时候会出现无限递归 为啥呢? 9 File "C:\Users\Administrator\Desktop\new.py", line 12, in __setattr__10 self.name=value #如果程序是这样的话实例化对象的时候会出现无限递归 为啥呢?11 File "C:\Users\Administrator\Desktop\new.py", line 12, in __setattr__12 self.name=value #如果程序是这样的话实例化对象的时候会出现无限递归 为啥呢?13 File "C:\Users\Administrator\Desktop\new.py", line 12, in __setattr__14 self.name=value #如果程序是这样的话实例化对象的时候会出现无限递归 为啥呢?15 File "C:\Users\Administrator\Desktop\new.py", line 12, in __setattr__16 self.name=value #如果程序是这样的话实例化对象的时候会出现无限递归 为啥呢?17 ...18 ...19 ...20 File "C:\Users\Administrator\Desktop\new.py", line 12, in __setattr__21 self.name=value #如果程序是这样的话实例化对象的时候会出现无限递归 为啥呢?22 File "C:\Users\Administrator\Desktop\new.py", line 12, in __setattr__23 self.name=value #如果程序是这样的话实例化对象的时候会出现无限递归 为啥呢?24 RecursionError: maximum recursion depth exceeded while calling a Python object25 >>>

上面的坑 详见 源代码注释 . 

躲开这些坑的办法就是 当你重写这些魔法方法之后 , 剩余的 就让原来的官方方法就解决 . 

1 # 这是一个 求面积的程序 , 如果属性名定义为 square的话 就默认 width=height 2 class Rectangle: 3     def __init__(self,width=0,height=0): 4         self.width=width 5         self.height=height 6  7     def __setattr__(self,name,value): 8         if name=='suqare': 9             self.width=valuc10             self,height=value11         else:12             self.__dict__[name]=value13             #super().__setattr__(name,value)14             #self.name=value             #如果程序是这样的话实例化对象的时候会出现无限递归  为啥呢?15             16     def GetArea(self):              # 在 最初的 init 那里开始对一个不存在的属性进行赋值 然后就调用了 setattr  调用 setattr的时候 又有 对 该属性(不存在.)进行赋值 然后就递归了.17         return self.width*self.height   # 解决的办法就是 在出错的地方使用官方提供的 方法  super().__setattr__(name,value)
1 =============== RESTART: C:\Users\Administrator\Desktop\new.py =============== 2 >>> r1=Rectangle(4,5) 3 >>> r1.__dict__   # 将该实例化对象的 所有属性 打印出来 4 {
'height': 5, 'width': 4} 5 >>> r1.GetArea() 6 20 7 =============== RESTART: C:\Users\Administrator\Desktop\new.py =============== 8 >>> r1=Rectangle(4,5) 9 >>> r1.__dict__10 {
'width': 4, 'height': 5}11 >>> # 显然是可以的 .

 

转载于:https://www.cnblogs.com/A-FM/p/5678231.html

你可能感兴趣的文章
关于函数指针的总结
查看>>
采用PHP函数uniqid生成一个唯一的ID
查看>>
Centos7安装32位库用来安装32位软件程序
查看>>
【HMOI】小C的填数游戏 DP+线段树维护
查看>>
java中23种设计模式之6-适配器模式(adapter pattern)
查看>>
Easy C 编程 in Linux
查看>>
poj3761(反序表)
查看>>
x86寄存器总结
查看>>
jquery easyui ajax data属性传值方式
查看>>
封装了些文件相关的操作
查看>>
什么是Solr
查看>>
poj2386(简单dfs)
查看>>
双链表的基本操作
查看>>
走进异步编程的世界 - 剖析异步方法(上)
查看>>
[HAOI2006]受欢迎的牛
查看>>
docker-maven-plugin 完全免Dockerfile 文件
查看>>
day20 Python 装饰器
查看>>
限制性与非限制性定语从句区别
查看>>
fiddler工具的使用
查看>>
jquery源码分析(二)——架构设计
查看>>