发布于 2016-05-30 19:27:35
这看起来像是创建一个简单的对象以将值保存在一行中的技巧。大多数内置对象不允许在它们上设置任意属性:
>>> 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__
方法分配属性,但这可能不值得使用样板。所以你可以做一个空的类:
>>> class Data(object): pass
>>> d = Data()
>>> d.x = 0
>>> d.x
0
显然,程序员不是没有意识到这一点,就是不希望在声明类的地方增加一行,并想出自己的解决办法来存储数据。事实证明,尽管函数是内置类型,但确实允许您向它们添加属性:
>>> def foo(): pass
>>> foo.x = 0
>>> foo.x
0
上面和lambda都允许您在一个语句中创建这样一个容器。我觉得这是个不错的主意。
发布于 2016-05-31 13:14:12
使用lambda:None函数的优点是什么?
这是怎么回事
eris = lambda:None
eris.jkcpp = ...
编写器使用函数对象的命名空间( __dict__
)。
这是非常罕见的。我会避免的。
名称空间是将合法的名称映射到对象的域,当您执行类似的操作时,名称空间的优点是名称空间不在本地和全局范围内,它们可以覆盖或覆盖相同名称指向不同对象的范围。
它表面上没有什么问题,但是如果其他人试图阅读代码来理解传递的这个函数是怎么回事,那么他们可能会想:
兰博达会被称为“羔羊”吗?我们为什么要到处转悠?返回None的可调用性不是很有用,这一定是某种黑客。
要避免混淆,请使用语义上理解为命名空间的对象。
命名空间
我们在Python3的标准库中有一个SimpleNamespace对象:
from types import SimpleNamespace
eris = SimpleNamespace()
eris.jkcpp = ...
在Python 2中,常见的做法是:
class NS(object):
pass
eris = NS()
eris.jkcpp = ...
如果您需要一个简单的命名空间,这些都是ok选项。
不利方面
然而,我还没有看到这些名称空间形式的大量使用。我要么发现,在我希望数据带有语义的情况下,名称元组就足够了(当有很多数据时特别有用),或者我使用的对象不仅仅是pass
。
尽管如此,它们实际上与简单的字典并没有什么不同。名称指向的值存储在对象的__dict__
中。您还可以传递一个dict
实例。虚点查找也增加了一些开销(在查看对象的字典之前,检查对象的类型是否有数据描述符)。
结论:
名称空间实例可能有一些缺点,但它可能更具可读性。可读性很重要。如果您认为您的程序需要一个简单的命名空间,请使用它。
但是,不要在名称空间中使用不需要任何操作的函数。这是误导性的,对任何人都没有意义。
https://stackoverflow.com/questions/37532208
复制相似问题