使用 lambda:None 函数作为命名空间的优势?
Advantage of using a lambda:None function as a namespace?
我看到了以下内容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],:,:])
我们可以为 lambda:None
定义的函数定义任意属性吗?
我在看一个casscf代码,这是量子化学中的一个算法,作者用这个lambda函数得到了2电子积分。
然后 decided against it,显然。
这看起来像是创建一个简单对象以在一行中保存值的技巧。大多数内置对象不允许您在其上设置任意属性:
>>> 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'
如果您自己制作 class,那么您可以添加任何您想要的属性。在这种情况下,您可以制作一个 class 其 __init__
方法分配属性,但这可能不值得样板。所以你可以做一个空的 class:
>>> class Data(object): pass
>>> d = Data()
>>> d.x = 0
>>> d.x
0
显然,程序员要么没有意识到这一点,要么不想要声明 class 的额外行,并提出了他们自己的存储数据的解决方法。事实证明,函数尽管是内置类型 do 允许您向它们添加属性:
>>> def foo(): pass
>>> foo.x = 0
>>> foo.x
0
以上内容和 lambda 都可以让您在一条语句中创建这样的容器。我实际上认为这是个好主意。
What is the advantage of using a lambda:None function?
这是怎么回事
eris = lambda:None
eris.jkcpp = ...
是作者正在使用函数对象的命名空间(__dict__
)。
这非常不常见。我会避免它。
名称空间 是合法 Python 名称映射到对象的域,当您执行上述操作时,命名空间 是名称不在本地和全局范围内,在这些范围内它们可以 覆盖或被覆盖,其中相同的名称旨在指向不同的对象。
从表面上看这没什么问题,但如果其他人试图阅读代码以了解传递的这个函数发生了什么,那么他们可能会想:
Will the lambda 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 对象:
from types import SimpleNamespace
eris = SimpleNamespace()
eris.jkcpp = ...
在 Python 2 中,通常会执行以下操作:
class NS(object):
pass
eris = NS()
eris.jkcpp = ...
如果您需要一个简单的命名空间,这些都是不错的选择。
缺点
但是,我还没有看到这些命名空间形式的大量使用。我要么发现 namedtuple 就足够了,我希望语义与数据一起携带(当它们很多时特别有用),要么我使用一个可变对象,其中不仅仅是 pass
。
实际上,它们在编程上与简单字典没有什么不同。名称指向的值存储在对象的 __dict__
中。您也可以传递一个 dict
实例。点查找也增加了一点开销(在查看对象的字典之前检查对象的类型是否有数据描述符)。
结论:
命名空间实例可能有一些缺点,但它可能更具可读性。可读性很重要。如果您认为您的程序需要一个简单的命名空间,请使用它。
但是不要对命名空间使用什么都不做的函数。它具有误导性,对任何人都没有意义。
我看到了以下内容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],:,:])
我们可以为 lambda:None
定义的函数定义任意属性吗?
我在看一个casscf代码,这是量子化学中的一个算法,作者用这个lambda函数得到了2电子积分。 然后 decided against it,显然。
这看起来像是创建一个简单对象以在一行中保存值的技巧。大多数内置对象不允许您在其上设置任意属性:
>>> 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'
如果您自己制作 class,那么您可以添加任何您想要的属性。在这种情况下,您可以制作一个 class 其 __init__
方法分配属性,但这可能不值得样板。所以你可以做一个空的 class:
>>> class Data(object): pass
>>> d = Data()
>>> d.x = 0
>>> d.x
0
显然,程序员要么没有意识到这一点,要么不想要声明 class 的额外行,并提出了他们自己的存储数据的解决方法。事实证明,函数尽管是内置类型 do 允许您向它们添加属性:
>>> def foo(): pass
>>> foo.x = 0
>>> foo.x
0
以上内容和 lambda 都可以让您在一条语句中创建这样的容器。我实际上认为这是个好主意。
What is the advantage of using a lambda:None function?
这是怎么回事
eris = lambda:None
eris.jkcpp = ...
是作者正在使用函数对象的命名空间(__dict__
)。
这非常不常见。我会避免它。
名称空间 是合法 Python 名称映射到对象的域,当您执行上述操作时,命名空间 是名称不在本地和全局范围内,在这些范围内它们可以 覆盖或被覆盖,其中相同的名称旨在指向不同的对象。
从表面上看这没什么问题,但如果其他人试图阅读代码以了解传递的这个函数发生了什么,那么他们可能会想:
Will the lambda 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 对象:
from types import SimpleNamespace
eris = SimpleNamespace()
eris.jkcpp = ...
在 Python 2 中,通常会执行以下操作:
class NS(object):
pass
eris = NS()
eris.jkcpp = ...
如果您需要一个简单的命名空间,这些都是不错的选择。
缺点
但是,我还没有看到这些命名空间形式的大量使用。我要么发现 namedtuple 就足够了,我希望语义与数据一起携带(当它们很多时特别有用),要么我使用一个可变对象,其中不仅仅是 pass
。
实际上,它们在编程上与简单字典没有什么不同。名称指向的值存储在对象的 __dict__
中。您也可以传递一个 dict
实例。点查找也增加了一点开销(在查看对象的字典之前检查对象的类型是否有数据描述符)。
结论:
命名空间实例可能有一些缺点,但它可能更具可读性。可读性很重要。如果您认为您的程序需要一个简单的命名空间,请使用它。
但是不要对命名空间使用什么都不做的函数。它具有误导性,对任何人都没有意义。