我看到了下面的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:
这是怎么回事
编写器正在为其
__dict__
使用函数对象创建命名空间。在命名空间是一个域,合法的Python名称映射到对象,当您执行上述操作时,名称空间的优势在于名称不在本地和全局范围内,在本地和全局范围内,名称可以被覆盖,或者在相同名称指向不同对象时被覆盖。
从表面上看,这没有什么错,但如果其他人试图阅读代码,以了解正在传递的这个函数发生了什么,那么他们可能会想:
为了避免混淆,请使用语义上理解为命名空间的对象。在
名称空间
在Python 3的标准库中有一个SimpleNamespace对象:
^{pr2}$在Python2中,通常会执行以下操作:
如果您需要一个简单的名称空间,这些是可以选择的。在
缺点
但是,我还没有使用这些形式的名称空间。我要么发现namedtuple可以满足我希望语义与数据一起传递的地方(当数据很多的时候特别有用),要么我使用一个不只是
pass
的可变对象。在实际上,它们在编程上与简单的字典没有什么不同。名称所指向的值存储在对象的
__dict__
中。您还可以传递一个dict
实例。点式查找也增加了一点开销(在查找对象字典之前检查对象的类型是否有数据描述符)。在结论:
命名空间实例可能有一些缺点,但它可能更具可读性。可读性很重要。如果您认为您的程序需要一个简单的名称空间,请使用它。在
但是不要对名称空间使用do-nothing函数。这是一种误导,对任何人都没有意义。在
这看起来像是在一行中创建一个简单对象来保存值的技巧。大多数内置对象不允许对其设置任意属性:
如果创建自己的类,则可以添加任何所需的属性。在这种情况下,您可以创建一个类,其
^{pr2}$__init__
方法分配属性,但这可能不值得作为样板。所以你只需创建一个空类:显然,程序员不是没有意识到这一点,就是不想在声明类的地方多出一行,而是想出了自己的方法来存储数据。结果表明,尽管函数是一个内置类型,但它允许您向它们添加属性:
上面的方法和lambda都允许您在单个语句中创建这样的容器。我真的认为这是个好主意。在
相关问题 更多 >
编程相关推荐