2025-09-10:仓库迁移
This commit is contained in:
65
8.类与对象/9.创建一种新形式的类属性或实例属性.py
Normal file
65
8.类与对象/9.创建一种新形式的类属性或实例属性.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# 如果想要创建一个新形式的实例属性,可以以描述符类的形式定义其功能
|
||||
# 所谓描述符就是以特殊方法__get__; __set__; __delete__的形式实现了三个核心属性的访问操作
|
||||
class Integer:
|
||||
# 存储名称
|
||||
def __init__(self,name):
|
||||
self.name = name
|
||||
|
||||
# 如果没有输入目标对象,就返回自身,如果输入了获取目标对象的__dict__属性里key是name的条目
|
||||
def __get__(self, instance, cls):
|
||||
# 这里的描述比较复杂
|
||||
# ,如果instance是空的,说明访问的是类,那么我们就要返回类本身
|
||||
# 如果instance不是空的,那说明是实例对象,需要返回实例的字段
|
||||
if instance is None:
|
||||
return self
|
||||
else:
|
||||
return instance.__dict__[self.name]
|
||||
|
||||
# 如果设置输入不是整数,就报错.否则往目标对象的__dict__属性中写入{name: value}
|
||||
def __set__(self, instance, value):
|
||||
if not isinstance(value, int):
|
||||
raise TypeError('value must be an integer')
|
||||
print("Set {} to {}".format(self.name, value))
|
||||
instance.__dict__[self.name] = value
|
||||
|
||||
# 将key为name的属性从目标对象的__dict__中移除
|
||||
def __delete__(self, instance):
|
||||
del instance.__dict__[self.name]
|
||||
|
||||
class Point:
|
||||
# 先设置x和y(其实是初始化self.x和self.y)
|
||||
x = Integer('x')
|
||||
y = Integer('y')
|
||||
|
||||
# 实例化的时候调用
|
||||
def __init__(self,x,y):
|
||||
# 调用Integer的__set__方法来给元素赋值
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
p = Point(2,3)
|
||||
p.x
|
||||
p.y
|
||||
# 很明显,如果我首先初始化一个b,然后对b使用__set__方法指定p作为插入对象,那这个类就有麻烦了
|
||||
b = Integer('b')
|
||||
print("\n{:-^18}".format("这里有脏东西"))
|
||||
b.__set__(p, 3)
|
||||
print("{:-^18}\n".format("这里有脏东西"))
|
||||
# 这说明一件事,如果对实例的__dict__属性进行操作,那么我们就可以搞到一个动态类
|
||||
|
||||
# 初始化一定要在实例化之前进行,否则就只能用拙劣的__set__方法了,这就比较丑陋了
|
||||
class Point:
|
||||
# 实例化的时候调用
|
||||
def __init__(self, x, y):
|
||||
# 先设置x和y
|
||||
self.x = Integer('x')
|
||||
self.y = Integer('y')
|
||||
# 调用Integer的__set__方法来给元素赋值
|
||||
self.x.__set__(self, x)
|
||||
self.y.__set__(self, y)
|
||||
|
||||
p = Point(2,3)
|
||||
p.x
|
||||
p.y
|
||||
|
||||
# 当然,这样做会很爽,但如果你只需要给某个特定类中的一种属性加东西,最好还是使用property重写
|
Reference in New Issue
Block a user