如何在 Python 中包含宏?
How to include macros in Python?
This 是一个类似的问题,但我的目标不是性能而是可读性。
假设我有不同的 Behaviours
,它们共享一个重复的函数 f1()
。
from abc import ABCMeta, abstractmethod
class Behavior:
__metaclass__ = ABCMeta
@abstractmethod
def run(self):
pass
class Behavior1(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 1.
f1()
class Behavior2(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 2.
f1()
class Behavior3(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 3
f1()
我希望 f1()
能够访问 run()
中的实例属性和局部变量,而无需将它们作为参数传递。
也许我可以在 Behavior
中实现它,但我无法访问 localVar
。
from abc import ABCMeta, abstractmethod
class Behavior:
__metaclass__ = ABCMeta
@abstractmethod
def run(self):
pass
def f(self):
print(self.data*localVar)
class Behavior1(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 1.
f1()
self.f()
class Behavior2(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 2.
f1()
self.f()
class Behavior3(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 3
f1()
self.f()
是否有任何 pythonic 或 OOP 方式为 f1()
编写 C 样式宏?
宏不是 python 中的固有构造,因为没有像 C++ 中那样的预处理器可供使用。
因此,您所做的任何让您只编写一次代码的事情都必须完成...
在 python 之外(即您手动使用 gcc 的预处理器);或
通过使用 python 中的调试信息(即解构调用堆栈)
前者比较麻烦,但是可行
后者也是一个痛点,但也是可行的。
但是,由于您的目标是提高可读性,因此这些选项都不好,因为习惯了 python 的任何人都完全不知道您在做什么。将语言结构从其他语言移植到 python.
时要非常小心
如果您的函数需要修改局部变量,那么您将不得不在每个地方编写相同的代码行。
如果它只需要使用它们,我强烈建议只传递参数 - 或者重新考虑您的设计并需要许多派生 类 在一个函数中做大致相同的事情(即如果你破坏了那个"function" 分成函数的几个部分,让派生的 类 只覆盖他们想要的部分?)。
你真正想要的听起来像 "access to outer scope variables" 这不是全局的。
如果您使用 python3.x,您应该查找 nonlocal keyword。
如果您使用 python2.x,请尝试使用可变对象作为对象的包装器。
其实我的回答是基于this一个
This 是一个类似的问题,但我的目标不是性能而是可读性。
假设我有不同的 Behaviours
,它们共享一个重复的函数 f1()
。
from abc import ABCMeta, abstractmethod
class Behavior:
__metaclass__ = ABCMeta
@abstractmethod
def run(self):
pass
class Behavior1(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 1.
f1()
class Behavior2(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 2.
f1()
class Behavior3(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 3
f1()
我希望 f1()
能够访问 run()
中的实例属性和局部变量,而无需将它们作为参数传递。
也许我可以在 Behavior
中实现它,但我无法访问 localVar
。
from abc import ABCMeta, abstractmethod
class Behavior:
__metaclass__ = ABCMeta
@abstractmethod
def run(self):
pass
def f(self):
print(self.data*localVar)
class Behavior1(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 1.
f1()
self.f()
class Behavior2(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 2.
f1()
self.f()
class Behavior3(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 3
f1()
self.f()
是否有任何 pythonic 或 OOP 方式为 f1()
编写 C 样式宏?
宏不是 python 中的固有构造,因为没有像 C++ 中那样的预处理器可供使用。
因此,您所做的任何让您只编写一次代码的事情都必须完成...
在 python 之外(即您手动使用 gcc 的预处理器);或
通过使用 python 中的调试信息(即解构调用堆栈)
前者比较麻烦,但是可行
后者也是一个痛点,但也是可行的。
但是,由于您的目标是提高可读性,因此这些选项都不好,因为习惯了 python 的任何人都完全不知道您在做什么。将语言结构从其他语言移植到 python.
时要非常小心如果您的函数需要修改局部变量,那么您将不得不在每个地方编写相同的代码行。
如果它只需要使用它们,我强烈建议只传递参数 - 或者重新考虑您的设计并需要许多派生 类 在一个函数中做大致相同的事情(即如果你破坏了那个"function" 分成函数的几个部分,让派生的 类 只覆盖他们想要的部分?)。
你真正想要的听起来像 "access to outer scope variables" 这不是全局的。
如果您使用 python3.x,您应该查找 nonlocal keyword。
如果您使用 python2.x,请尝试使用可变对象作为对象的包装器。
其实我的回答是基于this一个