类和对象-魔法方法
__init__方法
在对象初始化的时候实现个性化定制,在类实例化的时候自动进行调用。
语法: __init__(self[, ..])
__new__ 方法
在__init__方法调用前被调用,对象是由该方法进行创建,实例化对象调用的第一个方法就是该方法。
语法: __new__(cls[, ..])
一般在类的继承中,继承的是不可变类型的类,使用 __new__ 方法,可以对不可变的类进行继承修改,另一个是在元类中定制类。
| Python |
|---|
| # 定义类,继承str类,并使用new方法可以将不可变对象进行修改,比如以下进行从写str类,默认将字符串都变成大写
class Capstr(str):
# 在继承str之前使用new方法在str类创建对象之前进行自定义,然后再执行str的new方法
def __new__(cls, string):
string = string.upper()
return super().__new__(cls, string)
# 定义对象
test = Capstr("aBc")
# 可以发现默认都将字符串进行大写
print(test) # ABC
# 同样可以继续使用str对应的方法,将字符串变为小写
print(test.lower()) # abc
|
__del__方法
在对象即将被销毁的时候执行方法的内容。
语法: __del__(self)
注意: 并不是删除销毁对象都会执行 __del__ 方法,只有检测到该对象没有任何引用的时候才会将它销毁,然后再执行 __del__方法。
| Python |
|---|
| # 创建类C,并定义del方法
class C:
def __init__(self):
print("对象创建成功~")
def __del__(self):
print("对象销毁成功~")
# 创建对象执行init方法
c = C() # 对象创建成功~
# 对象销毁执行del方法
del c # 对象销毁成功~
# 如果创建的对象存在其他变量的引用,则不会执行del语句
a = C()
s = a
del a
print(12345)
# 执行顺序
# 对象创建成功~
# 123456
# # 对象销毁成功~
|
通过 __del__方法将函数销毁前传递出去
| Python |
|---|
| # 方法一,通过全局变量的方式进行传递(不推荐)
class A:
def __init__(self, name):
self.name = name
def __del__(self):
# 创建全局变量x,将self值传递给x
global x
x = self
a = A(123)
del a
print(x.name)
# 方法二,通过函数进行传递(闭包函数)
# 创建类A,定义__del__方法,将函数进行传递
class A:
def __init__(self, name, func):
self.name = name
self.func = func
def __del__(self):
self.func(self)
# 通过闭包函数进行值的传递,当调用闭包函数a的时候,传入了函数self参数,此时修改了函数外部变量x等于self,就将self传递出来,当不适用参数调用闭包函数则执行的是return x,此时就把self函数调用了
def a():
x = 0
def b(y=None):
nonlocal x
if y:
x = y
else:
return x
return b
# 将闭包函数外部函数赋值给c
c = a()
# 通过创建对象,将c函数传递给类
e = A(123, c)
print(e) # <__main__.A object at 0x101031fa0>
# 删除对象e,此时将执行__del__方法,实际执行的是闭包函数内部函数,然后将值进行返回c
del e
# 将c赋值给变量g,此时,g就是类对象的self
g = c()
print(g) # <__main__.A object at 0x101031fa0>
print(g.name) # 123
|
属性访问相关魔法方法
hasattr 函数
判断某个属性是否存在。
| Python |
|---|
| # 定义类
class Test:
def __init__(self, name, age):
self.name = name
self._age = age
test = Test("aa", 18)
print(hasattr(test, "name")) # True
print(hasattr(test, "_Test__age")) # True
|
getattr 函数魔法方法 __getattribute__ 和 __getattr__
getattr: 获取某个属性。
__getattribute__ 魔法方法: 当访问对象的属性,会被该方法拦截,执行该方法内容。
__getattr__魔法方法: 当访问对象的属性不存在,会先执行 __getattribute__ 魔法方法,然后执行 __getattr__魔法方法。
| Python |
|---|
| # getattr函数
# 定义类
class Test:
def __init__(self, name, age):
self.name = name
self._age = age
test = Test("aa", 18)
print(getattr(test, "name")) # aa
print(getattr(test, "_Test__age")) # 18
# 对应魔法方法
class Test:
def __init__(self, name, age):
self.name = name
self.__age = age
# 当使用函数getattr则会调用该魔法方法
def __getattribute__(self, item):
print("被__getattribute__拦截")
return super().__getattribute__(item)
# 当使用函数getattr查询不存在对象属性这回执行该魔法方法
def __getattr__(self, item):
if item == "111":
print(111)
else:
print("没有该元素")
test = Test("aaa", 18)
print(getattr(test, "name"))
# 被__getattribute__拦截
# aaa
getattr(test, "111")
# 被__getattribute__拦截
# 111
getattr(test, "222")
# 被__getattribute__拦截
# 没有该元素
|
setattr 函数魔法方法 __setattr__
设置某个属性。
| Python |
|---|
| # setattr函数
# 定义类
class Test:
def __init__(self, name, age):
self.name = name
self._age = age
test = Test("aa", 18)
setattr(test, "name", "bb")
setattr(test, "_Test__age", 19)
print(getattr(test, "name")) # bb
print(getattr(test, "_Test__age")) # 19
# 对应魔法方法
class Test:
def __setattr__(self, name, value):
self.__dict__[name] = value
test = Test()
test.name = "aa"
print(test.name) # aa
|
delattr 函数
删除某个属性。
| Python |
|---|
| # delattr函数
# 定义类
class Test:
def __init__(self, name, age):
self.name = name
self._age = age
test = Test("aa", 18)
delattr(test, "name")
print(hasattr(test, "name")) # False
# 对应魔法方法
class Test:
def __setattr__(self, key, value):
self.__dict__[key] = value
def __delattr__(self, item):
self.__dict__.pop(item)
test = Test()
test.name = "aa"
print(test.__dict__) # {'name': 'aa'}
del test.name
print(test.__dict__) # {}
|