如何防止直接设置实例属性?
How to prevent setting instance attribute directly?
假设我有一个 class A
class A:
__slots__ = ['_x']
def __init__(self):
self._x = 10
@property
def x(self):
return self._x
而且我想限制从除其他实例的方法之外的任何地方分配给 a._x
。
我该怎么做?在 Python 中甚至可能吗?
关键是要写一个 class 属性只能在特定方法内更改,而不能直接从外部更改。
Python 并没有真正像 C++ 那样的“私有”变量。即使您使用 PEP8 中的 _
前缀将变量设置为私有(正如您所做的那样)。您始终可以使用 A._x
.
访问变量
如果出于某种原因要模拟私有变量,可以使用 __
(双下划线)前缀,因为它会破坏名称。类似地,您可以使用 @property
装饰器来制作 getter 和 setter 函数并防止访问该属性。但是,即使这些也会失败,因为您可以使用 __dict__
.
直接访问变量
所以 Pythonic 方法是保持原样。 Python 在这方面就像 perl。套用 Perl 书中关于隐私的名言,
the philosophy is that you should stay out of the living room because
you weren't invited, not because it is defended with a shotgun.
我完全同意@kinshukdua 的观点。但是,只是为了探索更多可供您选择的选项。您可以通过放置一些条件
来覆盖 setattr
这可能不是最 pythonic 的方式,但我愿意接受一种更简洁的方式来实现这一目标。
class A:
_x = 10 #dont think you need an init method since you are not adding any data
def __setattr__(self, key, value):
if 'yes' in value[1]:
super().__setattr__(key,value[0])
else:
raise TypeError('You should not have access to this')
def change(self, value,loc= 'yes'):
self._x = value,loc
return self._x
假设我有一个 class A
class A:
__slots__ = ['_x']
def __init__(self):
self._x = 10
@property
def x(self):
return self._x
而且我想限制从除其他实例的方法之外的任何地方分配给 a._x
。
我该怎么做?在 Python 中甚至可能吗?
关键是要写一个 class 属性只能在特定方法内更改,而不能直接从外部更改。
Python 并没有真正像 C++ 那样的“私有”变量。即使您使用 PEP8 中的 _
前缀将变量设置为私有(正如您所做的那样)。您始终可以使用 A._x
.
如果出于某种原因要模拟私有变量,可以使用 __
(双下划线)前缀,因为它会破坏名称。类似地,您可以使用 @property
装饰器来制作 getter 和 setter 函数并防止访问该属性。但是,即使这些也会失败,因为您可以使用 __dict__
.
所以 Pythonic 方法是保持原样。 Python 在这方面就像 perl。套用 Perl 书中关于隐私的名言,
the philosophy is that you should stay out of the living room because you weren't invited, not because it is defended with a shotgun.
我完全同意@kinshukdua 的观点。但是,只是为了探索更多可供您选择的选项。您可以通过放置一些条件
来覆盖 setattr这可能不是最 pythonic 的方式,但我愿意接受一种更简洁的方式来实现这一目标。
class A:
_x = 10 #dont think you need an init method since you are not adding any data
def __setattr__(self, key, value):
if 'yes' in value[1]:
super().__setattr__(key,value[0])
else:
raise TypeError('You should not have access to this')
def change(self, value,loc= 'yes'):
self._x = value,loc
return self._x