python魔法方法详解_Python魔术方法详解
写这个的初衷主要是因为网上充斥的大量的假冒伪劣解释说明
好歹自己试一试再写文章啊! 真的是误人子弟
例如: __ getattr__:获取一个不存在的属性时调用的方法 事实上获取任何属性的时候都会调用这个方法(包括存在和不存在的属性)
1. __init __ 和 __new __
__init__(self)
这个方法是一个对象方法,它主要是用来构建对象属性的
当对象创建的时候,就需要给这个对象赋予属性 这个时候,这个对象就开始自动调用了
by tokiea (简书)
class A:
def __init__(self):
print('开始给对象赋予属性了')
a = A()
__________________________________
`开始给对象赋予属性了`
def __new__(cls, *args, **kwargs):
这个方法是一个类方法,它用来创建对象的
也就是对象创建的时候最先调用的方法
通常会用来做单例模式和对象创建计数
*args, **kwargs是用来接收和传递创建对象时的参数
by tokiea (简书)
class A:
def __init__(self, name, age=1): # 实例方法
print('开始给对象赋予属性了')
self.name = name
self.age = age
def __new__(cls, *args, **kwargs): # 类方法
print('开始新建对象了')
print('我是参数args', args)
print('我是参数kwargs', kwargs)
return object.__new__(cls)
# 必须要有返回值 返回创建出来的实例
a = A('小明', age=2)
__________________________________
`开始新建对象了`
`我是参数args ('小明',)`
`我是参数kwargs {'age': 2}`
`开始给对象赋予属性了`
2.__ getattr__ 和 __ setattr__
很好理解的字面意思
获取属性和设置属性时调用的方法
__getattr__(self, item)
当获取实例化后的对象属性时,会自动调用的方法,好像除了阻止别人直接获取属性之外没特别大的用处了
用了这个方法之后,所有的实例对象属性都是需要在这里返回的,否则就是None值
by tokiea (简书)
class A:
def __init__(self, name, age=1):
self.name = name # 我想多凑几个字数
self.age = age
def __getattr__(self, item):
print('报告老大,有人在调用我的属性', item)
if item =='name':
return '不告诉你'
a = A('小明', age=2)
print(a.name)
print(a.age)
__________________________________
`报告老大,有人在调用我的属性 name`
`不告诉你`
`报告老大,有人在调用我的属性 age`
`None`
__setattr__(self, key, value):
这个方法比__getattr __要好用一些
设置属性的时候调用(当然初始化的时候也会调用一次)
可以用来判断属性设置的值(也可以改变即将设置的属性值)
by tokiea (简书)
class A:
def __init__(self, name):
self.name = name # 我想多凑几个字数
self.age = 1
def __setattr__(self, key, value):
print('开始给实例对象赋值了', key, value)
if key == 'age' and value:
# 这个可以做判断或者改变赋值的操作
if isinstance(value, int):
pass
else:
print('赋值错误,请填整数类型')
a = A('小明')
a.age = 10
a.age = '十八'
__________________________________
`开始给实例对象赋值了 name 小明`
`开始给实例对象赋值了 age 1`
`开始给实例对象赋值了 age 10`
`开始给实例对象赋值了 age 十八`
`赋值错误,请填整数类型`
3. __ enter __和 __ exit __
__enter__(self)
__exit__(self, exc_type, exc_val, exc_tb)
这两个方法就是用with的时候使用的,上下文管理
而且是 都要有
否则就会报错,差不多就像干将和莫邪,杨过和大雕,缺一不可
三个参数:
exc_type 错误类型
exc_val 错误原因
exc_tb 错误发生的内存地址
by tokiea (简书)
class A:
def __init__(self, name):
self.name = name # 我想多凑几个字数
self.age = 1
def __enter__(self):
print('我要进去了,嘿嘿嘿')
def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type)
print(exc_val)
print(exc_tb)
print('我要出去了')
a = A('小明')
with a:
print('我进来了')
a.age = 1/0 # 0不能做被除数 会报错
__________________________________
`Traceback (most recent call last):`
`我要进去了,嘿嘿嘿`
`我进来了`
`File ".....................py", line 18, in `
`a.age = 1/0`
`ZeroDivisionError: division by zero`
``
`division by zero`
``
`我要出去了`
4. __del __
__del__(self)
就是被删除的时候调用的方法
python自带垃圾回收 当对象没有引用的时候就会自动触发垃圾回收 自动调用 __del __ 方法
by tokiea (简书)
class A:
def __del__(self):
print('啊!我被删除了')
a = A()
del a # 这句 可有可无 因为程序运行结束会自动触发
__________________________________
`啊!我被删除了`
PS 刚好看研究了一下描述符 也写一点吧
__get __ , __set __ 和 __delete __
__get__(self, instance, owner)
看参数 instance 实例 owner 拥有者 就知道一个是拥有者 一个是被拥有 肯定需要两个对象
class A:
def __get__(self, instance, owner):
print('A:我被(实例)%s调用了,它属于 %s 类'%(instance,owner))
class B:
a = A()
b=B()
B.a
b.a
__________________________________
`A:我被(实例)None调用了,它属于 类`
`A:我被(实例)<__main__.B object at 0x0000028F0BC00CC0>调用了,它属于 类`
__set__(self, instance, value)
参数 一个是实例 一个是值
class A:
def __set__(self, instance, value):
print('我是A:我监听到了:%s被实例:%s设置成了属性' % (value, instance))
class B:
pass
a = A()
b = B()
B.a = a # 把实例对象a 先赋值给 类对象B 的类属性 a
b.a = 12345 # 再把 12345 赋值给实例对象b 的a
print(B.a)
print(b.a)
__________________________________
`我是A:我监听到了:12345被实例:<__main__.B object at 0x0000016923F90CC0>设置成了属性`
`<__main__.A object at 0x0000016923F90C88>`
`<__main__.A object at 0x0000016923F90C88>`
最后发现不管是实例对象b 还是类对象B 它们的a属性都是a实例 即使实例b进行了重新赋值12345的操作,也没能改变实例b的a属性
我想知道为什么 求教大佬
by tokiea (简书)
__delete__(self, instance)
class A:
def __delete__(self, instance):
print('实例对象%s把我删除了'%instance)
class B:
pass
a = A()
b = B()
B.a = a # 把实例对象a 先赋值给 类对象B 的类属性 a
b.a = 12345 # 再把 12345 赋值给实例对象b 的a
del b.a
print(b.a)
__________________________________
`实例对象<__main__.B object at 0x0000029510180CC0>把我删除了`
`<__main__.A object at 0x0000029510180C88>`
发现最后a实例没有被b实例删除 而是只调用了a的__delete __方法
by tokiea (简书)
未完待续 -- tokiea
python魔法方法详解_Python魔术方法详解相关推荐
- python魔术方法print_Python中的魔术方法入门
介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",中文称『魔术方法』,例如类的初始化方法 __init__ ,P ...
- php魔术方法 效率,PHP常用魔术方法的性能探究
性能往往是衡量代码很重要的一个标准.我们日常编码中经常会用到一些魔术方法,这些PHP提供的魔术方法是否会影响我们程序的性能呢?是否需要减少魔术方法 的使用呢?本文将通过测试对比来了解魔术方法对性能的影 ...
- php魔术方法的理解,php魔术方法的认识
在php中将所有以"__"即两个下划线开头的类方法保留为魔术方法,PHP中魔术方法有"__construct()"."__destruct()&quo ...
- python 多继承与super使用详解_Python super()方法、多继承以及MRO顺序
仅供学习,转载请注明出处 单独调用父类的方法 需求:编写一个类,然后再写一个子类进行继承,使用子类去调用父类的方法1. 使用方法1打印: 胖子老板,来包槟榔. 那么先写一个胖子老板的父类,执行一下: ...
- mysql 魔术设置_详解php魔术方法(Magic methods)的使用方法
PHP中把以两个下划线__开头的方法称为魔术方法,这些方法在PHP中充当了举足轻重的作用. 魔术方法包括: __construct(),类的构造函数 __destruct(),类的析构函数 __cal ...
- python创建实例会调用哪些魔术方法_Python最会变魔术的魔术方法,我觉得是它!...
作者:豌豆花下猫 来源:Python猫 在,我有一个核心的发现:Python 内置类型的特殊方法(含魔术方法与其它方法)由 C 语言独立实现,在 Python 层面不存在调用关系. 但是,文中也提到了 ...
- python魔法方法学不懂_Python进阶:Python魔法方法
密圈内有好几个同学问我:学习完了Python基础之后,学些什么呢? 看到这个问题之后,我没在考虑学习基础之后学什么,而我在想真的学完了吗?想以前我也是对着w3c对着廖雪峰的网上教程学习了一遍Pytho ...
- python 元类 详解_Python 元类详解 __new__、__init__、__call__、__metacalss__
了解元类之前,先了解几个魔术方法: __new__.__init__.__call__ __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪 ...
- python中的__call__和__repr__魔术方法
__call__:实现了__call__的对象是可调用的 __repr__:实现了__repr__的对象可以输出对象的相应属性信息 比如说: class Student:def __init__(se ...
最新文章
- net start mysql启动mysql,提示发生系统错误 5 拒绝访问 解决方法
- AI理论知识整理(17)-子式,非奇异,可逆
- 139.00.007 Git学习-Cheat Sheet
- 拓扑排序排课系统_视频结构化人脸布控系统
- Multi GET API介绍
- JVM虚拟机-Class文件简介
- 计算机的软硬件发展进程,计算机软件的发展演变简介
- Vue3学习之第三节:setup()中使用计算属性
- 2017 Material design 第三章第四节《字体与排版》
- 符合 Qi 规范的移动设备无线充电解决方案
- Sql Sugar使用仓储实现增删改查
- Linux 命令大全
- 知识产权与标准规范: 著作权法、计算机软件保护条例、商标权、不正当竞争法、招投标法、采购法、合同法
- 【python】什么是序列,Python序列详解
- 在线教育机构如何运营微信公众号
- 2023最新计算机毕业设计题目汇总大全
- pdf工具类之添加页码
- Samba 服务使用的端口和协议
- 根据出生日期计算年龄(精确到天)
- 解决pycharm官网无法访问