魔法方法
Posted oiqwyig
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了魔法方法相关的知识,希望对你有一定的参考价值。
常用魔法方法
魔法方法:是指方法名以两个下划线开头并以两个下划线结尾的方法
特点:调用时不需要人为调用,只要在特定条件下就会自动触发运行
构造方法
init方法
- 类名加括号产生一个空对象的时候自动触发,给对象添加独有数据
class Test:
def __init__(self, name, age):
self.name = name
self.age = age
print("名字:" + self.name)
print("年龄:" + self.age)
if __name__ == \'__main__\':
a = Test("小李", "18")
# -------输出结果---------
名字:小李
年龄:18
del方法
- 对象在被删除的时候自动触发(主动删除)当所有代码执行完成结束,整个名称空间都要删除(被动删除)
class Test:
def __init__(self):
print("初始化对象")
def __del__(self):
print("对象被删除了")
if __name__ == \'__main__\':
a = Test()
print("end")
# -------输出结果---------
初始化对象
对象被删除了
new方法
__new__
是对象实例化时第一个调用的方法,它只取下cls
参数,并把其他参数传给__init__
。__new__
很少使用,但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候
class Singleton:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
print("这个类没有创建")
cls._instance = super().__new__(cls, *args, **kwargs) # 使用父类的方法来创建类
print("这个类已经创建")
return cls._instance
s = Singleton()
s2 = Singleton() # s 和 s2 是同一个类,其共用一个内存地址
类的表示
str方法
- 对象被执行打印操作的时候自动触发,返回值必须是字符串类型
class Test:
def __init__(self):
pass
def __str__(self):
return "test_name"
if __name__ == \'__main__\':
a = Test()
print(a)
# -------输出结果---------
test_name
repr方法
- 返回值是str类型的,当我们直接在
shell
中输入对象名并按下回车,就会自动调用该方法,他也有和__str__
一样的功能,但如果两者你都重写了,在使用print
时,__str__
的优先级高,__repr__
是给机器看的,__str__
是给人看的,举个例子
>>> class A:
def __str__(self):
return \'我真帅\'
def __repr__(self):
return \'我是世界第一帅\'
>>> a = A()
>>> a
我是世界第一帅
>>> print(a)
我真帅
上下文管理器
enter方法
- 当对象被当做
with
上下文管理操作的开始自动触发,该方法返回什么,as
后面的变量名就得到什么
exit方法
- 对象被with语法执行完毕后自动触发,第一个参数代表追溯信息
class Closer:
\'\'\'一个上下文管理器,可以在with语句中
使用close()自动关闭对象\'\'\'
def __init__(self, obj):
self.obj = obj
def __enter__(self, obj):
return self.obj # 绑定到目标
def __exit__(self, exception_type, exception_value, traceback):
try:
self.obj.close()
except AttributeError: # obj不是可关闭的
print \'Not closable.\'
return True # 成功地处理了异常
访问控制
getattr方法
- 对象点不存在的名字自动触发,该方法返回什么,对象获取不存在的属性名就会得到什么,不返回默认为None,形参item就是对象想要获取的不存在的属性名
setattr方法
- 给对象添加或修改数据时会自动触发
对象.属性=属性名
一定要小心使用__setattr__
,这个列表最后的例子中会有所展示
delattr方法
- 这个魔法方法和
__setattr__
几乎相同,只不过它是用于处理删除属性时的行为自动触发。和__setattr__
一样,使用它时也需要多加小心,防止产生无限递归(在__delattr__
的实现中调用del self.name
会导致无限递归)
class AccessCounter(object):
\'\'\' 一个包含了一个值并且实现了访问计数器的类
每次值的变化都会导致计数器自增\'\'\'
def __init__(self, val):
super(AccessCounter, self).__setattr__(\'counter\', 0)
super(AccessCounter, self).__setattr__(\'value\', val)
def __setattr__(self, name, value):
if name == \'value\':
super(AccessCounter, self).__setattr_(\'counter\', self.counter + 1)
# 使计数器自增变成不可避免
# 如果你想阻止其他属性的赋值行为
# 产生 AttributeError(name) 就可以了
super(AccessCounter, self).__setattr__(name, value)
def __delattr__(self, name):
if name == \'value\':
super(AccessCounter, self).__setattr__(\'counter\', self.counter + 1)
super(AccessCounter, self).__delattr__(name)
容器内部魔法方法
getitem方法
- 定义对容器中某一项使用
self[key]
的方式进行读取操作时的行为。这也是可变和不可变容器类型都需要实现的一个方法。它应该在键的类型错误式产生TypeError
异常,同时在没有与键值相匹配的内容时产生KeyError
异常
setitem方法
- 定义对容器中某一项使用
self[key]
的方式进行赋值操作时的行为。它是可变容器类型必须实现的一个方法,同样应该在合适的时候产生KeyError
和TypeError
异常
可调用对象
call方法
- 允许类的一个实例像函数那样被调用。本质上这代表了
x()
和x.__call__()
是相同的。注意__call__
可以有多个参数,这代表你可以像定义其他任何函数一样,定义__call__
,喜欢用多少参数就用多少
魔法方法大全
魔法方法 | 什么时候被调用 | 解释 |
---|---|---|
__new__(cls [,...]) |
instance = MyClass(arg1, arg2) |
__new__ 在实例创建时调用 |
__init__(self [,...]) |
instance = MyClass(arg1,arg2) |
__init__ 在实例创建时调用 |
__cmp__(self) |
self == other, self > other 等 |
进行比较时调用 |
__pos__(self) |
+self |
一元加法符号 |
__neg__(self) |
-self |
一元减法符号 |
__invert__(self) |
~self |
按位取反 |
__index__(self) |
x[self] |
当对象用于索引时 |
__nonzero__(self) |
bool(self) |
对象的布尔值 |
__getattr__(self, name) |
self.name #name不存在 |
访问不存在的属性 |
__setattr__(self, name) |
self.name = val |
给属性赋值 |
__delattr_(self, name) |
del self.name |
删除属性 |
__getattribute__(self,name) |
self.name |
访问任意属性 |
__getitem__(self, key) |
self[key] |
使用索引访问某个元素 |
__setitem__(self, key) |
self[key] = val |
使用索引给某个元素赋值 |
__delitem__(self, key) |
del self[key] |
使用索引删除某个对象 |
__iter__(self) |
for x in self |
迭代 |
__contains__(self, value) |
value in self, value not in self |
使用in进行成员测试 |
__call__(self [,...]) |
self(args) |
“调用”一个实例 |
__enter__(self) |
with self as x: |
with声明的上下文管理器 |
__exit__(self, exc, val, trace) |
with self as x: |
with声明的上下文管理器 |
__getstate__(self) |
pickle.dump(pkl_file, self) |
Pickle |
__setstate__(self) |
data = pickle.load(pkl_file) |
Pickle |
以上是关于魔法方法的主要内容,如果未能解决你的问题,请参考以下文章