【问题标题】:Best way to return value in instance method在实例方法中返回值的最佳方式
【发布时间】:2018-01-26 16:17:53
【问题描述】:

我很好奇在 Python 中为实例方法返回值的推荐方法。如果这是一个相当琐碎的问题,我很抱歉,但我似乎无法在 google/sx/so 上找到正确的答案。

选项 1:

class Cla:
    def __init__(self):
        self.var = False

    def _inst_mtd(self):
        var = True
        return var

    def calc_var(self):
        self.var = self._inst_mtd()    # or in init if desired

    def return_var(self):
        return self.var

选项 2:

class Cla:
    def __init__(self):
        self.var = False

    def _inst_mtd(self):
        self.var = True

    def calc_var(self):
        self._inst_mtd()

    def return_var(self):
        return self.var

选项 3:

class Cla:
    def __init__(self):
        self.var = False

    def _inst_mtd(self):
        self.var = True
        return self.var

    def calc_var(self):
        self.var = self._inst_mtd()

    def return_var(self):
        return self.var

_inst_mtd 的目的是计算self.var 的值。返回self.var 的单独公共方法将向外部调用者提供return 函数。 _inst_mtd 意味着在类中调用,可能在循环中调用,也可能使用公共方法 calc_var,例如,如果运行需要一段时间。

我担心如果_inst_mtd 的全部目的是修改self.var 而不是实际处理另一个名为var 的变量,那么1 可能会导致局部变量和实例变量之间的混淆。对于 2,我的印象是(仅考虑 _inst_mtd)这构成了副作用,应该避免吗?但是 3 似乎没有必要,尽管它确实适用于返回类型注释,尤其是当 _inst_mtd 中的类型(不推荐)或其中的元素发生更改时。

【问题讨论】:

  • 免责声明:这是第一次发布在软件工程中,但没有人在那里回复。请务必指出可能的重复项,当我尝试搜索时,我找不到任何谈论这个特定示例的内容。帖子已被删除,以避免重复发布。
  • 我 python 你不需要任何return_var(self) 类型的方法。所有类变量都是公共的。
  • 我在想return_var(self) 或get_var(self): 是给定的!
  • 选项 3 肯定是错误的,因为您在两个地方更新了 self.var。
  • 嗨 mrCarnivore,是的,我知道我们可以简单地执行 Cla.var 来检索 var 的值,稍后可能会使用一个接口跟进它,该接口将调用 return_var,允许我稍后用其他东西替换self.var?

标签: python coding-style python-3.5


【解决方案1】:

您过分强调公共/私人访问。在 Python 中,任何实例(方法、变量等)的每个成员都是公开可用的。因此,您通常甚至不会费心写特别的getter 或setters。而是:

c = Cla()
c.var = 42
print(c.var)

完全可以接受。如果您仍然想提示其他程序员该变量应该是私有的并且不要被弄乱,您通常会在它前面加上一个下划线:self._var。然而,这只是一个约定。更多信息请见https://stackoverflow.com/a/1301369/1269892

【讨论】:

  • 嗨!感谢您的答复。想象一下,如果在某些客户端代码中调用它,并且某天后我决定让return_var 返回除self.var 之外的其他内容。提供访问方法对以后没有帮助吗?
  • 如果您正在创建某种 API,那么您的客户端类当然应该有某种保证,即代码仍然可以工作。因此,如果它是可以存储为变量的非常简单的东西并且该变量的名称不会改变,那么就选择简单的self.var。不过这种情况很少发生,因此您可以选择创建一个方法self.compute_stuff()。如果你创建了一个方法,你有责任选择一个好的名字而不是改变返回值。如果你真的改变了,你有责任让你的客户知道。
  • 嗯,确实如此。很抱歉,return_var 的命名有些混乱。我的印象是我们应该构建我们的代码,以便它 1. 易于重构和 2. 它不会影响调用代码?因此,我更喜欢return_func,我在 PR 期间收到了很多反馈:D 在您看来,使用 return func 与简单地使用 self.var 的优缺点是什么?
  • 如果你有一些非常简单的东西(只是存储一些值),那么你不需要方法。但是,如果您需要返回一些应该经常重新计算或需要很长时间重新计算的东西,那么您应该有一个方法。此外,如果“动词”在名称中更有意义,它应该是一种方法。如果是“名词”而且很简单——只是一个变量。
  • @Melvin 惯用的 Python 不使用 getter 和 setter。 Read this。相反,您使用属性,但前提是您决定稍后返回并控制访问。
【解决方案2】:

在这三种方法中,我认为选项 2 最有意义,因为每种方法的作用都很明确。但是如果_inst_mtd 真的不需要内部状态,就像选项 1 中那样,那么您可能应该将其设置为类之外的函数。在 Python 中,使用 getter 以防万一有一天您可能需要它们通常被认为是错误的方式,因为大多数时候它是一种多余的复杂性。此外,如果需要,您始终可以从公共方法中提取内部使用的方法。可以保留的简单性通常比为假设的未来需求而设计更有价值。

class Cla:
    def __init__(self):
        self.var = False

    def calc_var(self):
        self.var = True

instance = Cla()
instance.calc_var()
value = instance.var

【讨论】:

  • 哦,好吧,是的,到目前为止 1 也可能是一个静态方法,我打算让它为自己使用一些东西,是的,我应该在问题中添加它,对不起 >。calc_var(Cla()) 调用它? 2 应该是 :) 谢谢!
猜你喜欢
  • 2012-08-17
  • 2020-09-03
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 2015-07-27
  • 2014-10-15
  • 1970-01-01
  • 2012-07-14
相关资源
最近更新 更多