在 numexpr 表达式中使用对象属性
Use object attribute in numexpr expression
我正在尝试在 numexpr
表达式中使用对象属性。
最明显的做法是:
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.zeros(10)
o = MyClass()
o.a
b = ne.evaluate("o.a+1")
导致以下错误
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-22-dc90c81859f1> in <module>()
10 o.a
11
---> 12 b = ne.evaluate("o.a+1")
~/.local/lib/python3.5/site-packages/numexpr/necompiler.py in evaluate(ex, local_dict, global_dict, out, order, casting, **kwargs)
799 expr_key = (ex, tuple(sorted(context.items())))
800 if expr_key not in _names_cache:
--> 801 _names_cache[expr_key] = getExprNames(ex, context)
802 names, ex_uses_vml = _names_cache[expr_key]
803 arguments = getArguments(names, local_dict, global_dict)
~/.local/lib/python3.5/site-packages/numexpr/necompiler.py in getExprNames(text, context)
706
707 def getExprNames(text, context):
--> 708 ex = stringToExpression(text, {}, context)
709 ast = expressionToAST(ex)
710 input_order = getInputOrder(ast, None)
~/.local/lib/python3.5/site-packages/numexpr/necompiler.py in stringToExpression(s, types, context)
296 names.update(expressions.functions)
297 # now build the expression
--> 298 ex = eval(c, names)
299 if expressions.isConstant(ex):
300 ex = expressions.ConstantNode(ex, expressions.getKind(ex))
<expr> in <module>()
AttributeError: 'VariableNode' object has no attribute 'a'
咨询 another question,我使用 numexpr
的 global_dict
:
得到了一个不太令人满意的解决方案
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.zeros(10)
o = MyClass()
o.a
b = ne.evaluate("a+1", global_dict={'a':o.a})
一旦 MyClass
有十几个属性并且有一些这样的调用 ne.evaluate
。
有没有一种简单、干净的方法来做到这一点?
如果您的对象开始具有很多属性,您主要关心的似乎是 evaluate
调用的 scalability/maintainability。您可以通过传递 vars(o)
:
来自动化这部分
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.arange(10000)
self.b = 2*self.a
o = MyClass()
c = ne.evaluate("a+b", local_dict=vars(o))
请注意,我使用了 local_dict
,因为将这些名称放入本地名称空间可能会稍微快一些。如果实例属性有可能与脚本中的本地名称发生冲突(这在很大程度上取决于您如何命名属性以及 class 的作用),将 vars
作为 global_dict
就像问题中的一样(出于同样的原因 )。
您仍然需要跟踪实例属性与其在 numexpr 表达式中的名称之间的对应关系,但是使用上述内容可以跳过大部分工作。
您可以使用对象的 __dict__
属性来执行此操作。这将 return 一个字典,其中键是属性的名称(作为字符串),值是该属性本身的实际值。
因此,例如,您问题中的代码如下所示:
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.zeros(10)
o = MyClass()
o.a
b = ne.evaluate("a+1", global_dict=o.__dict__) # Notice the .__dict__
但是,某些对象可能没有 __dict__
属性。所以,相反,我做了一个小函数来做同样的事情:
def asdict(obj):
objDict = {}
for attr in dir(g):
objDict[attr] = getattr(g, attr)
return objDict
请注意,此函数还将包括方法和某些隐藏属性,例如 __module__
和 __main__
我正在尝试在 numexpr
表达式中使用对象属性。
最明显的做法是:
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.zeros(10)
o = MyClass()
o.a
b = ne.evaluate("o.a+1")
导致以下错误
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-22-dc90c81859f1> in <module>()
10 o.a
11
---> 12 b = ne.evaluate("o.a+1")
~/.local/lib/python3.5/site-packages/numexpr/necompiler.py in evaluate(ex, local_dict, global_dict, out, order, casting, **kwargs)
799 expr_key = (ex, tuple(sorted(context.items())))
800 if expr_key not in _names_cache:
--> 801 _names_cache[expr_key] = getExprNames(ex, context)
802 names, ex_uses_vml = _names_cache[expr_key]
803 arguments = getArguments(names, local_dict, global_dict)
~/.local/lib/python3.5/site-packages/numexpr/necompiler.py in getExprNames(text, context)
706
707 def getExprNames(text, context):
--> 708 ex = stringToExpression(text, {}, context)
709 ast = expressionToAST(ex)
710 input_order = getInputOrder(ast, None)
~/.local/lib/python3.5/site-packages/numexpr/necompiler.py in stringToExpression(s, types, context)
296 names.update(expressions.functions)
297 # now build the expression
--> 298 ex = eval(c, names)
299 if expressions.isConstant(ex):
300 ex = expressions.ConstantNode(ex, expressions.getKind(ex))
<expr> in <module>()
AttributeError: 'VariableNode' object has no attribute 'a'
咨询 another question,我使用 numexpr
的 global_dict
:
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.zeros(10)
o = MyClass()
o.a
b = ne.evaluate("a+1", global_dict={'a':o.a})
一旦 MyClass
有十几个属性并且有一些这样的调用 ne.evaluate
。
有没有一种简单、干净的方法来做到这一点?
如果您的对象开始具有很多属性,您主要关心的似乎是 evaluate
调用的 scalability/maintainability。您可以通过传递 vars(o)
:
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.arange(10000)
self.b = 2*self.a
o = MyClass()
c = ne.evaluate("a+b", local_dict=vars(o))
请注意,我使用了 local_dict
,因为将这些名称放入本地名称空间可能会稍微快一些。如果实例属性有可能与脚本中的本地名称发生冲突(这在很大程度上取决于您如何命名属性以及 class 的作用),将 vars
作为 global_dict
就像问题中的一样(出于同样的原因
您仍然需要跟踪实例属性与其在 numexpr 表达式中的名称之间的对应关系,但是使用上述内容可以跳过大部分工作。
您可以使用对象的 __dict__
属性来执行此操作。这将 return 一个字典,其中键是属性的名称(作为字符串),值是该属性本身的实际值。
因此,例如,您问题中的代码如下所示:
import numpy as np
import numexpr as ne
class MyClass:
def __init__(self):
self.a = np.zeros(10)
o = MyClass()
o.a
b = ne.evaluate("a+1", global_dict=o.__dict__) # Notice the .__dict__
但是,某些对象可能没有 __dict__
属性。所以,相反,我做了一个小函数来做同样的事情:
def asdict(obj):
objDict = {}
for attr in dir(g):
objDict[attr] = getattr(g, attr)
return objDict
请注意,此函数还将包括方法和某些隐藏属性,例如 __module__
和 __main__