何时将事物存储为实例的一部分而不是返回它们?

问题描述 投票:0回答:5

我只是想知道何时将事物存储为类实例的一部分以及何时使用方法返回事物。例如,以下哪一项更好:

class MClass():

    def __init__(self):
        self.x = self.get_x()
        self.get_y()
        self.z = None
        self.get_z()

    def get_x(self):
        return 2

    def get_y(self):
        self.y = 5 * self.x

    def get_z(self):
        return self.get_x() * self.x 

关于这类事情的约定是什么?我什么时候应该将东西分配给 self 以及什么时候应该返回值?这本质上是公共/私人的区别吗?

python properties getter-setter
5个回答
4
投票
  1. 您不应该
    return
    __init__
    中的任何内容。
  2. Python 不是 Java。您不需要为所有内容都添加
    get
  3. 如果
    x
    始终为 2,
    y
    始终为 10,而
    z
    始终为 12,则代码量很大。

做出一些假设,我会写那个课程:

class MClass(object):

    def __init__(self, x):
        self.x = x

    def y(self):
        return self.x * 5

    def z(self):
        return self.x + self.y()

>>> c = MClass(2)
>>> c.x
2
>>> c.y() # note parentheses
10
>>> c.z()
12

这允许

x
稍后更改(例如
c.x = 4
),并且仍然为
y
z
提供正确的值。


2
投票

您可以使用

@property
装饰器:

class MClass():

    def __init__(self):
        self.x = 2

    @property
    def y(self):
        return 5 * self.x

    #here a plus method for the setter
    @y.setter
    def y(self,value):
        self.x = y/5   

    @property    
    def z(self):
        return self.x * self.x 

这是组织您的访问器的好方法


2
投票

据我所知,这方面没有“惯例”,尽管有一些常见的做法,不同的语言有所不同。

在Python中,人们普遍认为“一切都是公共的”,并且根本没有理由有一个getter方法只是为了返回实例变量的值。但是,如果您需要在访问此类变量时对实例执行操作,则可能需要这样的方法。

例如,您的

get_y
方法仅在每次访问值时都需要 重新计算 表达式 (
5 * self.x
) 才有意义。否则,您应该简单地在
y
的实例中定义
__init__
变量 - 它更快(因为您不需要每次都重新计算值)并且它使您的意图清晰(因为任何查看您的代码的人都会立即知道值不变)

最后,有些人更喜欢使用属性而不是编写纯粹的 get/set 方法。 这个问题

有更多信息

2
投票

我将您的问题视为一般的面向对象开发问题,而不是特定于 python 的问题。因此,成员数据的一般规则是,仅当数据作为特定实例的一部分相关时,才将数据保存为类的成员。

例如,如果您有一个具有两个维度(高度和宽度)的 Screen 对象。这两个应该存储为成员。与特定实例关联的区域将返回与特定实例的高度和宽度关联的值。

如果某些事情看起来应该即时计算,但可能会被一遍又一遍地调用,您也可以将它们缓存为成员,但这确实是您在确定它是有效之后应该做的事情权衡(额外的成员以换取更快的运行时间)。


1
投票

get
应该始终按照它所说的去做。
get_y()
get_z()
不要这样做。

最好做:

class MClass(object):
    def __init__(self):
        self.x = 2

    @property
    def y(self):
        return 5 * self.x

    @property
    def z(self):
        return self.x * self.x

这使得

y
z
始终取决于
x
的值。

你可以做

c = MClass()
print c.y, c.z # 10, 4
c.x = 20
print c.y, c.z # 100, 400
© www.soinside.com 2019 - 2024. All rights reserved.