实现此目的的更好方法是使用装饰器,为此您有两种选择:
基于函数的装饰器:
您可以创建一个基于函数的装饰器,它接受乳胶表示形式作为参数,并将其附加到它装饰的函数上:
def latex_repr(r):
def wrapper(f):
f.latex = r
return f
return wrapper
然后您可以在定义函数时使用它并提供适当的表示:
@latex_repr(r'$ax^2 + bx + c$')
def func(x, a, b, c):
return a*x**2 + b*x + c
这翻译为:
func = latex_repr(r'$ax^2 + bx + c$')(func)
并使得latex
属性在定义函数后立即可用:
print(func.latex)
'$ax^2 + bx + c$'
我已将表示形式设为必需参数,如果您不想强制始终给出表示形式,则可以定义一个合理的默认值。
基于类的装饰器:
如果您更喜欢类,那么基于类的装饰器也可以比您最初的尝试以更 Pythonic 的方式用于实现类似的效果:
class LatexRepr:
def __init__(self, r):
self.latex = r
def __call__(self, f):
f.latex = self.latex
return f
你以同样的方式使用它:
@LatexRepr(r'$ax^2 + bx + c$')
def func(x, a, b, c):
return a*x**2 + b*x + c
print(func.latex)
'$ax^2 + bx + c$'
Here LatexRepr(r'$ax^2 + bx + c$')
初始化类并返回可调用实例(__call__
定义)。其作用是:
func = LatexRepr(r'$ax^2 + bx + c$')(func)
# __init__
# __call__
并做同样的事情wrapped
does.
由于它们都只是向函数添加一个参数,因此它们只是按原样返回它。他们不会用另一个可调用的来替换它。
尽管基于类的方法可以解决问题,但基于函数的装饰器应该更快、更轻量。
You additionally asked:
"because Python is "lazy" in executing functions": Python just compiles the function body, it doesn't execute any statements inside it; the only thing it does execute is default argument values (See famous Q here https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument/34172768#34172768). That's why you first need to invoke the function for it to 'obtain' the attribute latex
.
The additional downside to this approach is that you execute that assignment everytime you invoke the function