【问题标题】:Naming convention for accessor methods in Python [closed]Python中访问器方法的命名约定[关闭]
【发布时间】:2021-10-27 17:03:21
【问题描述】:

Q1:来自 OO 背景(Java、Ruby、Smalltalk),在 Python 中编写类时,命名访问器和修改器方法的首选方式是什么?例如,如果我有:

class Account :
    def __init__(self, owner) : 
        self.__owner = owner
        self.__amount = 0
    def owner(self) :
        return self.__owner

我应该在属性名称之后调用我的访问器方法,如 owner() 来访问私有属性 __owner,这是 Smalltalk 和 Ruby 等语言中的自定义,或者更确切地说是调用它 get_owner,这将是蛇- case 等价于在 Java 中调用访问器的方式。我认为 Java 方式会更受欢迎?

Q2:对于 mutator 方法的类似问题:我应该将它们称为 set_owner à la Java 还是其他?

Q3:最后一个问题:如果我的属性是公开的,例如:

class Account :
    def __init__(self, owner) : 
        self.owner = owner
        self.amount = 0

我是否应该费心为它们编写访问器和修改器方法,因为无论如何我都可以从类外部访问和分配这些属性?

【问题讨论】:

  • 改用属性。
  • 查看 @property 装饰器。
  • 不要在 Python 中使用 getter 和 setter
  • 注意,双下划线名称修改并不是真正的私有。单个下划线用于表示不属于公共 API 的属性。 请不要编写样板的 getter 和 setter
  • “这意味着最好的近似方法可能是使用 Java 风格的命名约定并在课程中的某处添加一个脚注,以便真正的 Pythonistas 会使用装饰器”NO。同样,“真正的 pythonista”的做法是只使用常规属性,即您的 Account 类将只是 __init__,只有 self.owner = ownerself.amount = 0 看看this answer I wrote to a related question 解释了“不要写 getter 和 setter”哲学背后的原因。

标签: python naming-conventions smalltalk accessor


【解决方案1】:

AFAIK 的私有属性在 Python 中不像其他语言那样强调。每个属性都很容易访问,因此绕过“私有”属性的专用 getter/setter 主要是荣誉系统。所以这将是首选:

class Account :
    def __init__(self, owner) : 
        self.owner = owner
        self.amount = 0

a = Account("Kim")
a.owner
a.amount
a.owner = "Carol"
a.amount = 100

现在,人们提到了属性。这是一种使用 getter 和 setter 来“伪造”不存在的属性的方法,因此您仍然可以使用属性语法 x.y = z。它与x.set_y(z) 做同样的事情,所以如果你不关心这种审美,请不要使用属性;实例方法调用并不比属性访问更“Pythonic”。

在 Python 中通常不使用属性来实现隐私。它们用于即时计算值的 getter/setter。单位转换就是一个很好的例子:

class Temperature:
    def __init__(self, Kelvin = 0.0):
        self.K = Kelvin
    
    @property
    def C(self):
        return self.K - 273.15
    
    @C.setter
    def C(self, Celsius):
        self.K = Celsius + 273.15

    @property
    def F(self):
        return self.C * 9/5 + 32
    
    @F.setter
    def F(self, Fahrenheit):
        self.C = (Fahrenheit - 32) * 5/9

因此,不是将相同的温度存储在 3 个不同的单位中,而是将其存储在开尔文中并使用 getter/setter 来获取摄氏温度或华氏温度。属性只是提供temp.K, temp.C, temp.F 而不是temp.K, temp.getC(), temp.getF() 的美学对称性。

【讨论】:

  • “AFAIK 私有属性在 Python 中不像其他语言那样强调”Python 没有访问修饰符,这不是强调的情况......但是 +1
  • 嗯,有一些命名约定,例如名为 _secret 的属性。你是对的,它实际上并没有做任何真正的事情,但它是开发人员和用户之间荣誉系统的一部分,不要弄乱这个属性。 IIRC 单个前导下划线名称不同的唯一真正方式是 from myModule import * 将忽略这些名称,但 import * 相当罕见
  • 是的,完全同意
  • 感谢@BatWannaBe 的回答;这与我与@juanpa.arrivillaga 的讨论在精神上非常接近
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多