使用lambda:None函数有什么好处?
这里发生了什么
eris = lambda:None eris.jkcpp = ...
是作者正在使用函数对象为其创建命名空间 __dict__ 。
__dict__
的 命名空间 强> 是合法的Python名称映射到对象的域,当您执行上述操作时, 的 命名空间的优点 强> 是名称不在他们可能的地方和全球范围内 覆盖或覆盖相同名称旨在指向不同对象的位置。
从表面上看,这并没有什么不妥,但如果其他人试图阅读代码来了解正在传递的这个功能正在发生什么,那么他们可能会想:
会不会被称为?为什么我们绕过一个可赎回的人?返回None的callable不是很有用,这必定是某种hack。
为避免混淆,请使用将在语义上理解为命名空间的对象。
我们在Python 3的标准库中有一个SimpleNamespace对象:
from types import SimpleNamespace eris = SimpleNamespace() eris.jkcpp = ...
在Python 2中,通常会执行以下操作:
class NS(object): pass eris = NS() eris.jkcpp = ...
如果您需要一个简单的命名空间,这些都是正常的选项
但是,我还没有使用这些形式的命名空间。我要么发现一个namedtuple就足以让我想要在数据中携带语义(特别是当它们有很多时都很有用)或者我使用的是一个可变对象而不仅仅是 pass 在里面。
pass
就像它们一样,它们在编程上与简单的字典完全没有区别。名称指向的值存储在对象中 __dict__ 。你也可以路过一个 dict 实例。虚线查找会增加一些开销(在查看对象的字典之前检查对象的类型是否具有数据描述符)。
dict
命名空间实例可能有一些缺点,但它可能更具可读性。可读性很重要。如果您认为您的程序需要一个简单的命名空间,请使用它。
但是不要对命名空间使用do-nothing函数。这是误导,对任何人都没有意义。
这看起来像是一个创建一个简单对象来保存一行中的值的技巧。大多数内置对象不允许您在它们上设置任意属性:
>>> object().x = 0 Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'object' object has no attribute 'x' >>> ''.x = 0 Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'str' object has no attribute 'x' >>> [].x = 0 Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'list' object has no attribute 'x'
如果您创建自己的类,则可以添加所需的任何属性。在这种情况下,你可以创建一个类 __init__ 方法分配属性,但这可能不值得使用样板。所以你可以创建一个空类:
__init__
>>> class Data(object): pass >>> d = Data() >>> d.x = 0 >>> d.x 0
显然,程序员要么不知道这个,要么不想要声明类的额外行,并且已经提出了自己的存储数据的解决方法。尽管是内置类型,但事实证明它是功能 做 允许您向它们添加属性:
>>> def foo(): pass >>> foo.x = 0 >>> foo.x 0
上面和lambda都可以在一个语句中创建这样的容器。我其实认为这是一个很好的主意。