【问题标题】:Is it best-practice to place __init__ in the beginning or end of a class?将 __init__ 放在课程的开头还是结尾是最佳实践吗?
【发布时间】:2011-09-07 14:05:48
【问题描述】:

考虑以下代码:

class AClass():

    def defaultMethod(self):
        return 1

    def __init__(self, methodToUse = defaultMethod):
        print (methodToUse(self))

if __name__== "__main__":
    AClass()

在这种情况下,不能将 defaultMethod 移动到 __init__ 方法下方,如果这样做,会导致“NameError: name 'defaultMethod' is not defined”

这意味着我需要在 __init__ 之前定义这个方法,否则 Python 不知道它。这再次意味着我不再将 __init__ 作为第一个方法,这让我想知道是否通常将 __init__ 方法放在类的末尾或开头。

【问题讨论】:

  • 邮政编码。声明方法的顺序不应该成为真正的问题,除非你正在做一些相当奇怪的事情。
  • 我仍然不明白如何要求在一个类中具有一定的方法顺序?你能举个例子吗?
  • @David 执行了你的代码,我没有发现任何错误
  • @eyquem 更改defaultMethod__init__ 的顺序,您会看到问题所在。编译器无法为 methodToUse 参数分配默认参数,因为在创建 __init__ 时该符号尚不存在。

标签: python design-patterns


【解决方案1】:

你是什么意思,“我需要在 init 之前定义这个方法,否则 Python 不知道它”?

>>> class A(object):
...     def __init__(self):
...         self.foo()
...     def foo(self):
...         print '42'
... 
>>> A()
42

我通常将 __init__() 放在其他实例方法之前,但在类方法/属性/属性之后。

【讨论】:

    【解决方案2】:

    我觉得你做事有点奇怪。如果不是第一种方法,您仍然应该将__init__ 放在高位。可读性是关键,__init__ 公开了您期望的主要实例字段。

    这里有三种选择。我的首选是第一个,因为它记录了默认方法,并且需要对您的代码进行最少的修改。最后一个可行,但可能会让任何必须维护您的代码的人感到困惑。

    class A(object):
        def __init__(self, method="foo"):
            if callable(method):
                method(self)
            else:
                getattr(self, method)()
        def foo(self):
            print "something"
    
    
    class B(object):
        def __init__(self, method = None):
            if method is None:
                self.defaultMethod()
            else:
                method(self)
        def defaultMethod(self):
            print "foo"
    
    
    def _defaultMethod(self):
        print self.x
    
    class C(object):
        def __init__(self, method = _defaultMethod):
            self.x = "bleh"
            method(self)
        def anotherMethod(self):
            print "doing something else"
        def defaultMethodProxy(self):
            _defaultMethod(self)
    

    【讨论】:

    • 我更喜欢第二种解决方案,主要是因为它类似于处理将空列表作为默认参数的方式。
    【解决方案3】:

    __init__ 最常放置在类的开头,因为它们是类实例化时运行的第一件事。由于您的情况要求它在班级中进一步存在,因此其他开发人员最好在班级的 cmets 中留下注释。

    【讨论】:

    • 评论用于向维护您的代码的开发人员发送消息。文档字符串适用于 API 用户。
    【解决方案4】:

    我更喜欢 init 在开头,实际上我不会那样写类,而是像这样:

    class AClass():
        def __init__(self, methodToUse = 'defaultMethod'):
            print getattr(self, methodToUse)()
    
        def defaultMethod(self):
            return 1
    
    if __name__== "__main__":
        AClass()
    

    问题是在编译时(创建默认参数时),没有函数defaultMethod,但如果你在__init__内部使用它,那么方法就在那里。

    【讨论】:

      猜你喜欢
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 2011-03-21
      相关资源
      最近更新 更多