如何为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 时,似乎 getset 函数是使用编写的@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 代码? [复制]

具有公共getter的抽象属性,可以在具体类中定义私有setter吗?

Ebean:如何为没有属性的getter创建列

Python中的setter和getter

Python随笔13

OroCommerce 如何为产品表的新字段查找 Getter 和 Setter