如何为python类中的私有属性编写getter-setter方法?
Posted
技术标签:
【中文标题】如何为python类中的私有属性编写getter-setter方法?【英文标题】:How to write getter-setter methods for a private attribute in python class? 【发布时间】:2021-08-08 00:36:36 【问题描述】: 操作系统:Windows 10,64 位 编辑器:VSCode 1.56.2 Python:3.9.0我有一个带有year
属性的课程。
当我想 private 这个 property 时,似乎 get 和 set 函数是使用编写的@property 和 @year.setter 装饰器不起作用。
class Ab():
def __init__(self, year):
self.__year = year
print(self.__year)
@property
def year(self):
return self.__year
@year.setter
def year(self, y):
if y < 8:
self.__year = 0
else:
self.__year = y
a = Ab(5)
实际输出:5
预期输出:0
我是 python 新手,所以提前感谢您的帮助。
【问题讨论】:
Python 没有定义访问修饰符。 @Nicholas Hunter 抱歉,我听不懂。这意味着因为它是私有的,所以即使在类中我们也不能修改它?!还是对于私有属性,我们无法将其转换为属性? 你永远不会分配给year
,只有__year
,所以永远不会调用setter。
@chepner 我把__放在方法之前,我的意思是def __year(self):
,但它给了我这个错误RecursionError: maximum recursion depth exceeded in comparison
那是因为它定义了一个名为__year
的类属性,它隐藏了实例属性,所以你最终会得到无限递归。 getter 和 setter 是 only 应该直接访问self.__year
的两个东西; 一切,包括其他方法,都应该通过该属性。
【参考方案1】:
您实际上从未修改过Ab.year
:
class Ab():
def __init__(self, year):
self.__year = year
self.year = year # <-- this needs to be here
print(self.__year)
@property
def year(self):
return self.__year
@year.setter
def year(self, y):
if y < 8:
self.__year = 0
else:
self.__year = y
a = Ab(5)
>>> 0
顺便说一句,除非您明确想要名称修改,否则使用双前导下划线是个坏主意。
【讨论】:
在__init__
中你根本不需要self.__year = ...
。
但是这一年不再是私人的了。
@Ghane 在 Python 中没有什么是真正私有的。如果这是您真正想要的,您可以将 Ab
转换为 Cython 扩展类型
@Lucas Ng 是的。在 python 之前,我学习了 Java。我以为我可以像在 Java 中那样私有化。谢谢。
您获得的隐私程度是单个下划线名称在导入时未绑定到命名空间【参考方案2】:
您需要在 __init__
中引用 setter,而不是 dunder 私有属性。
class Ab():
def __init__(self, year):
self.year = year
print(self.__year)
【讨论】:
有了这个,print(self.__year)
给了我预期的输出。但这对我来说有点奇怪。似乎 year 与 __year 有隐藏关系,但 __year 与 year 没有关系,我添加了这些行,从它们的输出中我说:self.year = year print(self.__year) self.__year = 1 print(self.__year)
是吗?
@Ghane - seems year have a hidden relationship with __year
- 使用 @property getter 和 setter 的一个原因是混淆了该属性的获取方式、来源以及计算方式。以上是关于如何为python类中的私有属性编写getter-setter方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 .h 中定义的属性在 .m 中为 Setter 和 Getter 自动生成 Xcode 5 代码? [复制]