【问题标题】:Python - what's your conventions to declare your attributes in a class?Python - 在类中声明属性的约定是什么?
【发布时间】:2010-12-30 10:39:53
【问题描述】:

在 Python 中,我可以在整个类中声明属性。例如:

class Foo:
def __init__(self):
    self.a = 0

def foo(self):
    self.b = 0

当我有一个包含很多属性的大类时,很难检索我的类中的所有属性。

是下面的代码(a)还是下面的代码(b)更好:

a)在这里,很难找到所有属性:

class Foo:
    def __init__(self):
        foo_1()
        foo_2()

    def foo_1(self):
        self.a = 0
        self.b = 0

    def foo_2(self):
        self.c = 0

b)在这里,很容易找到所有属性,但它漂亮吗?

class Foo:
    def __init__(self):
        (self.a, self.b) = foo_1()
        self.c = foo_2()

    def foo_1(self):
        a = 0
        b = 0
        return (a, b)

    def foo_2(self):
        c = 0
        return c

简而言之,您在类中声明属性的约定是什么?

编辑:

当然,这是一个简单的例子,我的代码没有必要在这里改进。试想一下在_init_() 中调用的具有大量“小方法”(用于划分我的代码、提高可读性)的复杂类。

【问题讨论】:

  • ... 我可以说以上都不是吗?我只是不让我的班级变得足够大而成为问题。
  • 您好,“以上都不是”?是否可以 ?那你怎么办? :-)
  • “那你怎么办?”简单的。不要让你的类变得足够大而成为一个问题。让你的班级更小。将事物分解为单独的类。简化。重点。

标签: python convention coding-style


【解决方案1】:

理想情况下,您的构造函数不应调用方法:a constructor should not do real work

如果属性数量不成比例地增长,你应该重构你的类,例如使用Extract Class将你的类分成几个类,从而尊重single responsibility principle

【讨论】:

    【解决方案2】:

    这是怎么回事:

    class Foo:
        def __init__(self):
            self.a = 0
            self.b = 1
            self.c = 2
    

    或者如果abc 有某种关联,您可以在一行中声明它们:

    class Foo:
        def __init__(self):
            self.a, self.b, self.c = 0, 1, 2
    

    或者,如果 abc 以某种方式相关并且您将它们初始化为相同的不可变值,则可以在单个赋值中声明它们:

    class Foo:
        def __init__(self):
            self.a = self.b = self.c = 0
    

    【讨论】:

    • 同意。 (吹毛求疵:在这个特定的例子中,你可以做self.a = self.b = self.c = 0 - 赋值不是表达式,但这种特殊情况是允许的;当然,这很少有用,并且在分配可变对象时具有不同的语义)。
    • 如果我的方法 _init_ 需要做很多事情,我更愿意将 _init_ 分成几个小方法。在这种情况下,是只在_init_中声明属性(见a)还是直接在小方法中声明属性(见b))
    • @SeyZ:尽管我不喜欢大型方法,但如果 init 变得这么大,那么您的类可能本身就很大(参见单一责任原则)。我们谈论多大?如果您想组织一些初始化,请在其间添加空行,并可能在整个段落中添加注释。
    • @delnan 好的,我明白了,所以最好有一些“段落”(上面有评论)而不是调用“私人”(用引号引起来:])方法来做我必须做的事情?
    • @SeyZ:我会这么说,是的。为它添加一个方法只会增加额外的线条和重量(以及一些傻瓜称之为并部分重新初始化对象的危险),最多具有最小的可读性奖励。如果您非常需要那种可读性,因为__init__ 中有一百件事要做,那么您的类可能还是太大了。
    【解决方案3】:

    首先,这里说的不是类属性,而是实例属性。我的约定是将它们全部放在构造函数中,如果它们在另一种方法中初始化,则值为 None 。这样我总能知道会发生什么。这有点像声明它们,尽管它不是强制性的。

    例如:

    class Foo(object):
        def __init__(self, a=None, b=None, c=None):
            self.a = a
            self.b = b
            self.c = c
    

    嗯,我也喜欢将初始化器作为关键字参数,它使它更灵活。我也可以通过这种方式轻松覆盖默认值。

    【讨论】:

      【解决方案4】:

      在 Python 中,我可以声明属性 全班同学。

      正确。

      很难全部找回 当我有 有很多属性的大类。

      不。 dir(object)obj.__dict__ 在那里很有帮助。此外,为什么要检索所有属性?

      在这里,很难找到所有 属性

      一个好的编辑器/IDE 可以帮助您找到定义。我用的是WingIDE,挺好用的。

      在这里,很容易找到所有 属性,但它漂亮吗?

      好吧,这个特殊的代码,也许不是,但在__init__ 或类中声明所有公共属性是很常见的(但当你这样做时要小心Jabberwock)。这样你就知道它们是可用的,这很好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        相关资源
        最近更新 更多