如何在 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一个