使用lambda:无函数作为命名空间?

2024-10-01 13:33:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我看到了下面的code

eris = lambda:None
eris.jkcpp = np.einsum('iipq->ipq', eriaa[:ncore[0],:ncore[0],:,:])
eris.jc_PP = np.einsum('iipq->pq', eriab[:ncore[0],:ncore[0],:,:])

{cd1>我们可以定义函数的任意属性吗?在

我正在读一个casscf代码,这是量子化学中的一个算法,作者用这个lambda函数来得到2电子积分。 然后decided against it,显然。在


Tags: lambda函数nonenpcodeppjcpq
2条回答

What is the advantage of using a lambda:None function?

这是怎么回事

eris = lambda:None
eris.jkcpp = ...

编写器正在为其__dict__使用函数对象创建命名空间。在

命名空间是一个域,合法的Python名称映射到对象,当您执行上述操作时,名称空间的优势在于名称不在本地和全局范围内,在本地和全局范围内,名称可以被覆盖,或者在相同名称指向不同对象时被覆盖。

从表面上看,这没有什么错,但如果其他人试图阅读代码,以了解正在传递的这个函数发生了什么,那么他们可能会想:

Will it ever be called? Why are we passing around a callable? A callable that returns None isn't very useful, this must be some kind of hack.

为了避免混淆,请使用语义上理解为命名空间的对象。在

名称空间

在Python 3的标准库中有一个SimpleNamespace对象:

^{pr2}$

在Python2中,通常会执行以下操作:

class NS(object): 
    pass

eris = NS()
eris.jkcpp = ...

如果您需要一个简单的名称空间,这些是可以选择的。在

缺点

但是,我还没有使用这些形式的名称空间。我要么发现namedtuple可以满足我希望语义与数据一起传递的地方(当数据很多的时候特别有用),要么我使用一个不只是pass的可变对象。在

实际上,它们在编程上与简单的字典没有什么不同。名称所指向的值存储在对象的__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__方法分配属性,但这可能不值得作为样板。所以你只需创建一个空类:

^{pr2}$

显然,程序员不是没有意识到这一点,就是不想在声明类的地方多出一行,而是想出了自己的方法来存储数据。结果表明,尽管函数是一个内置类型,但它允许您向它们添加属性:

>>> def foo(): pass
>>> foo.x = 0
>>> foo.x
0

上面的方法和lambda都允许您在单个语句中创建这样的容器。我真的认为这是个好主意。在

相关问题 更多 >