使用默认值初始化方法的参数

18

如果没有传入显式值,我想要用一些默认值初始化方法的参数 - 就像这样:

class Example
   def __init__(self, data = self.default_data()):
      self.data = data

   def default_data():
      # ....
      return something

我遇到了这个错误:

NameError: name 'self' is not defined

我该如何修复这个问题?


1
相关链接:https://dev59.com/9nNA5IYBdhLWcg3wAItP - Fred Foo
1个回答

24
这里常用的习语是将默认值设置为一些特殊值(通常是None,尽管有人建议使用Ellipsis),然后您可以进行检查。
class Example(object): #inherit from object.  It's just a good idea.
   def __init__(self, data = None):
      self.data = self.default_data() if data is None else data

   def default_data(self):  #probably need `self` here, unless this is a @staticmethod ...
      # ....
      return something

你可能还会看到使用 object() 来作为标志的实例。
SENTINEL = object()
class Example(object):
   def __init__(self, data = SENTINEL):
      self.data = self.default_data() if data is SENTINEL else data

这种方式的好处是你可以将 None 传递给你的函数,但也有一些缺点(请参见下面 @larsmans 的评论)。如果你不预见到需要将 None 作为一个有意义的参数传递给你的方法,那么我建议使用这种方式。

2
使用 object() 作为哨兵的缺点是它在文档字符串中显示非常丑陋,并且默认行为更难以通过显式手段获得,因此传递 None 是通常的做法(在标准库和我所知道的大多数其他 Python 库中都是如此)。 - Fred Foo
1
@larsmans - 我也喜欢使用 None,但如果你想传递 None,那么 object() 就是下一个最好的选择。如果你愿意,你可以继承 object 并重写 __repr__ 使 help 看起来更美观... 另外,如果你导入 Example,你也可以导入 SENTINEL - mgilson
如果使用Python 3.x,则继承自“object”是自动的。 - Noctis Skytower
1
@NoctisSkytower -- 我非常清楚这一点。但是,我发现尝试编写既能与python2.x又能与python3.x兼容的代码具有实际价值。此外,虽然有一个名为2to3的脚本,但没有3to2...继承自object可以使代码更具可移植性,而且这很容易做到。从这个角度来看,继承自object似乎是有意义的选择。 - mgilson
1
在3.x中,'...'编译成Ellipsis单例,所以你实际上可以使用foo(bar=...) - Eryk Sun
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接