接上哈哈哈

2023-11-08 18:15
文章标签 接上 哈哈哈

本文主要是介绍接上哈哈哈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2,当对象即将被销毁时,会调用__del__(self)魔法方法

>>> class C:
...     def __init__(self):
...             print("我来了")
...     def __del__(self):
...             print("我走了")
...
>>> c=C()
我来了
>>> del c
我走了
>>> c=C()
我来了
>>> b=c
>>> del c
>>> del b
我走了

只有当对象的引用被删除时才会调用__del__(self)魔法方法,例如上码中将c赋值给b,删除小c时没有触发魔法方法,放b也被删除时,才触发魔法方法。

3,利用重写__del__(self)来实现对象的重生

本质:通过创建一个该实例对象的新引用来推迟其销毁。

(1)通过全局变量

>>> class D:
...     def __init__(self,name):
...             self.name = name
...     def __del__(self):
...             global x
...             x=self
...
>>> d=D("小甲鱼")
>>> d
<__main__.D object at 0x000001374BC2B8B0>
>>> del d
>>> x
<__main__.D object at 0x000001374BC2B8B0>
>>> x.name
'小甲鱼'

(2)通过闭包

>>> class E:
...     def __init__(self,name,func):
...             self.name = name
...             self.func = func
...     def __del__(self):
...             self.func(self)
...
>>> def outter():
...     x = 0
...     def inner(y=None):
...             nonlocal x
...             if y:
...                     x = y
...             else:
...                     return x
...     return inner
...
>>> f = outter()
>>> e = E("小甲鱼",f)
>>> e
<__main__.E object at 0x000001374BDC5310>
>>> e.name
'小甲鱼'
>>> del e
>>> g = f()
>>> g
<__main__.E object at 0x000001374BDC5310>
>>> g.name
'小甲鱼'

通过闭包将self保存在外部函数的变量x中,内部函数的作用是窃取self对象。

P67,P68   运算相关的魔法方法

1,运算相关的魔法方法

2,对__add__(self,other)魔法方法重写

>>> class S(str):
...     def __add__(self,other):
...             return len(self) + len(other)
...
>>> s1 = S("FishC")
>>> s2 = S("Python")
>>> s1 + s2
11
>>> s1 + "Python"
11
>>> "FishC" + s2
'FishCPython'
#从 s1 + "Python" 和 "FishC" + s2 的结果来看,触发的魔法方法是加号前的一项的

3,__radd__() 方法

4,__iadd__()方法,实现运算加赋值

>>> class S(str):
...     def __iadd__(self,other):
...             return len(self) + len(other)
...
>>> s1 = S("Apple")
>>> s2 = "Banana"
>>> s1 += s2
>>> s1
11
>>> type(s1)
<class 'int'>

5,对__int__()魔法方法进行重写

实现中文大写数字转化为 int 类型。

6,

按位与:&

按位或:|

按位异或:^

按位取反:~,(涉及到补码)

7,__index__()魔法方法

对象被当作索引值时触发

>>> class C:
...     def __index__(self):
...             print("被拦截了")
...             return 3
...
>>> c = C()
>>> s = "FishC"
>>> s[c]
被拦截了
'h'

P69 属性访问相关的魔法方法

1,

hasattr()方法,判断对象中是否有某属性

getattr()方法,得到对象中某属性的值,(与:“对象 . 属性”  等价)

setattr()方法,设置对象中某属性的值,(与:“对象 . 属性 = other”  等价)

delattr()方法,删除对象中某属性

>>> class C:
...     def __init__(self,name,age):
...             self.name = name
...             self.__age = age
...
>>> c = C("小甲鱼",18)
>>> hasattr(c,"name")
True
>>> getattr(c,"name")
'小甲鱼'
>>> setattr(c,"name","老乌龟")
>>> getattr(c,"name")
'老乌龟'
>>> delattr(c,"name")
>>> hasattr(c,"name")
False

2,

getattr()方法对应的魔法方法是__getattribute__(),而不是__getattr__(),__getattr__()也是一个魔法方法,但未与getattr()对应

>>> class C:
...     def __init__(self,name,age):
...             self.name = name
...             self.__age = age
...     def __getattribute__(self,attrname):
...             print("拦截到了getattribute")
...             return super().__getattribute__(attrname)
...
>>> c=C("小甲鱼",18)
>>> getattr(c,"name")
拦截到了getattribute
'小甲鱼'
>>> c.name                    #与getattr(c,"name")等效
拦截到了getattribute
'小甲鱼'

这是super()调用的是父类object的__getattribute__方法,Python中所有类默认继承object,调用的object中的__getattribute__(attrname)方法的结果就是return attrname

3,__getattr__()魔法方法,不与getattr()对应,触发条件是,获取不存在的属性时触发

>>> class C:
...     def __init__(self,name,age):
...             self.name = name
...             self.__age = age
...     def __getattribute__(self,attrname):
...             print("拦截到了getattribute")
...             return super().__getattribute__(attrname)
...     def __getattr__(self,attrname):
...             print("拦截到了getattr")
...
>>> c = C("小甲鱼",18)
>>> c.name
拦截到了getattribute
'小甲鱼'
>>> c.na
拦截到了getattribute
拦截到了getattr

4,__setattr__()魔法方法

触发条件:当捕捉到对象出现赋值操作时。

容易出现无限递归

>>> class D:
...     def __setattr__(self,name,value):
...             self.name = value                #此句话也会触发__setattr__()魔法方法,
...                                              #形成无限递归
>>> d = D()
>>> d.name = "小甲鱼"
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "<stdin>", line 3, in __setattr__File "<stdin>", line 3, in __setattr__File "<stdin>", line 3, in __setattr__[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

解决方法

>>> class D:
...     def __setattr__(self,name,value):
...             self.__dict__[name] = value
...
>>> d = D()
>>> d.name = "小甲鱼"
>>> d.name
'小甲鱼'

5,__delattr__()魔法方法

__delattr__()魔法方法也要防止无限递归,

>>> class E:
...     def __delattr__(self,name):
...             del self.__dict__[name]
...
>>> e = E()
>>> e.name = "小甲鱼"
>>> e.__dict__
{'name': '小甲鱼'}
>>> del e.name
>>> e.__dict__
{}

P70

1,__getitem__() 和 __setitem__() 魔法方法

__getitem__()触发条件:对象被索引,被切片,被迭代

__setitem__()触发条件:对象被索引赋值,切片赋值

>>> class D:
...     def __init__(self,data):
...             self.data = data
...     def __getitem__(self,index):
...             print("hello~,getitem")
...             return self.data[index]
...     def __setitem__(self,index,value):
...             self.data[index] = value
...             print("hello~,setitem")
...
>>> d=D([11,2,3,4,5,6])
>>> d
<__main__.D object at 0x000001374BE8C730>
>>> d.data
[11, 2, 3, 4, 5, 6]
>>> d[0]
hello~,getitem
11
>>> d[1:3]
hello~,getitem
[2, 3]
>>> d[0]=111
hello~,setitem

1,__iter__(self) 和 __next__(self) 魔法方法

P71

1,__contains__魔法方法,对应 in,not in

该魔法方法的代偿现象:略

2,__bool__魔法方法,对应 bool

该魔法方法的代偿现象:略

3,比较运算符的魔法方法:略

P72

1,__call__(self[,args,...])魔法方法

2,__str__(self)和__repr__(self)魔法方法

3,  eval(str)函数:将str去引号后执行

P73

property()

1,

property 是 Python 中的一个内置装饰器,它允许您将一个方法转换为属性,从而可以以属性的方式访问和修改对象的值。使用 property 装饰器可以实现属性的读取、写入和删除操作的自定义逻辑。

property 装饰器通常与三个方法一起使用,这些方法定义了属性的行为:

(1)getter 方法:负责获取属性的值,通常命名为 get_xxx,其中 xxx 是属性的名称。

(2)setter 方法:负责设置属性的值,通常命名为 set_xxx,其中 xxx 是属性的名称。

(3)deleter 方法:负责删除属性的值,通常命名为 del_xxx,其中 xxx 是属性的名称。

以下是一个使用 property 装饰器的示例:

class D:def __init__(self, x):self._x= xdef get_x(self):return self._xdef set_x(self, value):if value < 0:raise ValueError("x cannot be negative")self._x = valuedef del_x(self):print("Deleting the x")del self._xx= property(get_x, set_x, del_x)
# 创建 D 对象
d= D(5)
# 读取属性
print(d.x)  # 输出: 5
# 设置属性
d.x= 10
print(d.x)  # 输出: 10
# 删除属性
del d.x  # 输出: Deleting the x

在上述示例中,D 类使用 property 装饰器定义了 x 属性的 getter、setter 和 deleter 方法。这使得 x 属性可以像普通属性一样被读取、设置和删除。

2,

用魔法方法实现上述功能

>>> class D:
...     def __init__(self, x):
...         self._x = x
...     def __getattribute__(self, name):
...         if name == "x":
...             return object.__getattribute__(self, "_x")
...         return super().__getattribute__(name)
...     def __setattr__(self, name, value):
...         if name == "x":
...             if value < 0:
...                 raise ValueError("x cannot be negative")
...             object.__setattr__(self, "_x", value)
...         else:
...             super().__setattr__(name, value)
...     def __delattr__(self, name):
...         if name == "x":
...             print("Deleting the x")
...             object.__delattr__(self, "_x")
...         else:
...             super().__delattr__(name)
...
>>> # 创建 D 对象
>>> d = D(5)
>>>
>>> # 读取属性
>>> print(d.x)  # 输出: 5
5
>>>
>>> # 设置属性
>>> d.x = 10
>>> print(d.x)  # 输出: 10
10
>>> # 删除属性
>>> del d.x  # 输出: Deleting the x
Deleting the x

3,property创建一个只读的对象

>>> class E:
...     def __init__(self):
...             self._x = 520
...     @property
...     def x(self):
...             return self._x
...
>>> e = E()
>>> e.x
520
>>> e.x = 250
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

换成非语法糖就是:

>>> class E:
...     def __init__(self):
...             self._x = 520
...     def x(self):
...             return self._x
...     x = property(x)
...
>>> e = E()
>>> e.x
520
>>> e.x = 250
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

为什么是只读呢:

property有三个参数,分别是获取,写入和删除,此处只传入了第一个参数,只能获取,不支持写入和删除。

用语法糖形式的情况下,传入三个参数

>>> class E:
...     def __init__(self):
...             self._x = 520
...     @property
...     def x(self):
...             return self._x
...     @x.setter
...     def x(self,value):
...             self._x = value
...     @x.deleter
...     def x(self):
...             del self._x
...
>>> e = E()
>>> e.x
520
>>> e.x = 250
>>> e.x
250
>>> e.__dict__
{'_x': 250}
>>> del e.x
>>> e.__dict__
{}

这篇关于接上哈哈哈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/371632

相关文章

快来看,奇葩的年底离职理由,哈哈哈...

点击上方“朱小厮的博客”,选择“设为星标” 后台回复”加群“加入公众号专属技术群 来源:PM圈子(pm1178) 一到年底跳槽季, 大家一定有很多想法吧? 攀到高枝,辞职吧。 薪资太少,辞职吧。 心情不好,辞职吧。 上司不给力,辞职吧。 身体不好,辞职吧。 职场中尔虞我诈太严重,辞职吧。 ...... 但是这些辞职信,你们这样写真的好么? 辞职理由:现在的工作配不上我的梦想。 点评:相

手把手带你实现C语言扫雷进阶(1)(接上回基础版扫雷,附上源码)

文章目录 一、扫雷进阶留下的问题二.非雷扩展周围不是雷函数三、标记雷函数四.查看排雷总时间五、扫雷进阶源码及总结 一、扫雷进阶留下的问题 我们先来看看之前讲扫雷基础的时候留下的一些问题: 是否可以选择游戏难度     ◦ 简单 9 * 9 棋盘,10个雷     ◦ 中等 16 * 16棋盘,40个雷     ◦ 困难 30 * 16棋盘,99个雷 如果排查位置不是雷,周围

【C++17 之 .base() 函数实现正向和反向迭代器之间的交换,原理及代码展示】接上一p

在 C++17 之前,如果你有一个反向迭代器(std::reverse_iterator)并希望获取其对应的正向迭代器,你通常需要做一些额外的转换或维护额外的正向迭代器。然而,从 C++17 开始,std::reverse_iterator 提供了一个 .base() 成员函数,使得从反向迭代器获取其基础的正向迭代器变得更加直接。 std::reverse_iterator 的 .base()

v8中使用TensorBoard进行训练可视化(可用于论文)(补充版,接上一篇文章)

我们可以边训练,边通过TensorBoard观察损失函数的变化,同时也可以通过TensorBoard去查看整体网络yaml结构,不再需要人工根据yaml去画网络结构了。 训练v8的时候,重新打开新的终端: 虚拟环境下输入并执行:(关闭魔法) tensorboard --logdir=D:\Pycharm-Projects\YOLOv8bishe\runs\train\v8-fire 执行后

OTL翻译(5) -- otl_stream类(接上)

33 otl_stream & operator>>(otl_long_unicode_string & s) 在定义了OTL_UNICODE或OTL_UNICODE_CHAR_TYPE宏情况下,返回UNICODE的LOB类型 34 otl_stream & operator>>(OTL_UNICODE_CHAR_TYPE&c) 在定义了OTL_UNICODE或OTL_UNICODE_

Idea的快捷键,瞎摸索,开心就好,哈哈哈

Idea的快捷键,瞎摸索,开心就好,哈哈哈 前言:如果你有强迫症,换了一个编辑器,最痛苦莫过于快捷键,不顺手了。这里自己瞎摸索的快捷键,贴一下,这里主要以实际应用为主,因为大量介绍的网上已经很多很多,So基本的不再叙述。 分享一下比较不错的Idea快捷键整理网址(出自同一作者):Eclipse vs. IDEA快捷键对比大全  和  十大Intellij IDEA快捷键 和 史上最

工作第四五周 : 博客专家哈哈哈

首先感谢 CSDN 能够授予我“博客专家”的称号,哈哈,虚荣心得到了小小的满足! 这个称号一方面是对我写博客价值的认可,另一方面也代表着对我自身水平的更高要求,需要继续努力才行。 这两周 说来也惭愧,两周前发版加班到3点,第二天就开始感觉身体不舒服。后来又搬了个家,好几天没休息好,就开始牙疼、发烧。去医院检查,原来是休息不好导致免疫力下降,细菌感染导致的冠周炎,还好看得早,不用拔牙。 唉,

BOJ 4228 哈哈哈

题目链接~~> 做题感悟:这题一看就知道要用状态压缩,本题和HDU 1429 胜利大逃亡(续)差不多。 解题思路:你可以把宝物压缩为二进制,例如:01001 代表你已经拿过 1 号和 4 号宝物了 0 代表相应的宝物没拿。用同样的方法把拿某个物品的前提条件也映射成二进制。假如你现在遇到 3 号宝物,如果3号宝物的前提条件是拿到 1 号 和 4 号宝物才能拿 3 号,那么前提条件可以用二进制表示

接上一篇:webpack中html-webpack-plugin的使用及配置生成html

1. 安装html-webpack-plugin: cnpm i html-webpack-plugin@2.24.1 -D 2. webpack.dev.config.js中配置: var path = require('path');// 引入html-webpack-pluginconst HtmlWebpackPlugin = require('html-webpack-plug