工作过程中我碰到有些属性在使用的时候,由于某些原因变成了空值,比如数据连接后的数据库操作对象,由于某些原因调用数据库的方法时候报错数据对象是None,导致无法进行数据操作,所以需要在调用的时候检查这个是否未None,如果是空值就建立这个instance。
方法1:用@property
在Python中,您可以使用特殊的装饰器 @property
和 @<method_name>.setter
来在调用成员或属性之前运行方法。这些装饰器允许您定义属性的getter和setter方法,以便在访问属性之前或之后执行其他逻辑。 以下是一个示例:
class MyClass:
def __init__(self):
self._my_attribute = None
@property
def my_attribute(self):
# 在访问属性之前执行的方法
self._pre_method()
return self._my_attribute
@my_attribute.setter
def my_attribute(self, value):
# 在设置属性之前执行的方法
self._pre_method()
self._my_attribute = value
def _pre_method(self):
# 在访问属性或设置属性之前执行的方法
print("Running pre-method")
my_object = MyClass()
my_object.my_attribute = 10 # 调用my_attribute的setter方法,会先执行_pre_method方法
print(my_object.my_attribute) # 调用my_attribute的getter方法,会先执行_pre_method方法
方法2:__getattribute__方法
类中定义特殊方法 __getattribute__
。这个方法在访问类的属性时会被调用。
在 __getattribute__
方法中,如果 self._my_attribute
为 None
,您可以使用 object
类来初始化该属性。
class MyClass:
def __init__(self):
self._my_attribute = None
def __getattribute__(self, name):
if name == '_my_attribute' and object.__getattribute__(self, '_my_attribute') is None:
object.__setattr__(self, '_my_attribute', self._initialize_my_attribute())
print("Running __getattribute__ method")
return object.__getattribute__(self, name)
def _initialize_my_attribute(self):
# 初始化_my_attribute的逻辑
return "Initialized Value"
my_object = MyClass()
print(my_object._my_attribute) # 第一次访问属性,会初始化_my_attribute
print(my_object._my_attribute) # 第二次访问属性,已经初始化过,直接返回值
在上面的示例中,我们在 __getattribute__
方法中检查属性名是否为 _my_attribute
,并且 self._my_attribute
是否为 None
。如果满足条件,我们使用 object.__setattr__(self, '_my_attribute', self._initialize_my_attribute())
来初始化属性。
这样,在第一次访问 _my_attribute
属性时,会执行初始化逻辑。在后续的访问中,由于 self._my_attribute
已经被初始化,将直接返回其值,而不会再次执行初始化逻辑。
请注意,为了避免无限递归,我们使用 object.__getattribute__(self, name)
来获取属性的值,而不是直接调用 super().__getattribute__(name)
。同样地,我们使用 object.__setattr__(self, '_my_attribute', value)
来设置属性的值,以避免再次调用 __setattr__
方法。