python - 如何以编程方式将绑定(bind)添加到 Python 中的当前类范围?

标签 python

虽然问题非常具体,但我也非常感谢一般性建议和其他方法,以使我的问题毫无意义。我正在构建人工智能程序的集合,许多函数和类需要处理许多不同的状态和导致状态之间转换的操作,因此我需要一种方法来表示状态和行动。请注意,我不是构建一个简单的状态机,而是构建许多不同的程序(代理),它们都采用状态并返回操作作为与环境交互的方式。

我可以使用字符串,但如果特定算法需要将附加信息与状态或操作关联起来,那就很困惑,并且在长时间运行的程序中一遍又一遍地比较字符串会浪费开销。其他类型的常量也会出现同样的问题。所以我最初的想法是使用嵌套类,如下所示:

class DerivedAgent(Agent):
    class StateA(State): pass
    class StateB(State): pass
    ...
    def do_something(state):
        if state is self.StateA:
           ...

这工作得相当好,但是如果有许多状态和操作,则可能会占用大量空间来声明所有它们,并且所有的 pass 语句都很烦人。我希望能够做一些类似的事情...

class DerivedAgent(Agent):
    states("StateA", "StateB", "StateC", ...)

但我没有找到让 states 方法将新创建的类型添加到 DerivedAgent 类的方法。我想我也许可以使用 inspect 模块来做到这一点,但这感觉对于一个小小的便利来说太过分了。使用这样的类型是一个坏主意吗?有更优雅的方法吗?代理类外部的代码需要能够访问状态和操作,并且将状态放入模块命名空间中并不是一个好的选择,因为给定的模块中可能有多个代理。

最佳答案

您可以使用元类,这样您最终会得到如下代码:

class DerivedAgent(Agent):
    __states__ = ['StateA', 'StateB', ...]

例如:

class AgentMeta(type):
    def __new__(meta, classname, bases, classdict):
        for clsname in classdict['__states__']:
            classdict[clsname] = type(clsname, (State,), {})
        return type.__new__(meta, classname, bases, classdict))

然后,只需重写您的 Agent 类,使其具有该行

#python3.x
class Agent(Base1, Base2, ..., BaseN, metaclass=AgentMeta):
    #everything else unchanged

# 2.2 <= python <= 2.7 
class Agent(Base1, Base2, ..., BaseN):
    __metaclass__ = AgentMeta
    #everything else unchanged

如果您不想更改 Agent 类,您只需在您创建的每个子类中包含适当的元类声明即可。

关于python - 如何以编程方式将绑定(bind)添加到 Python 中的当前类范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3453058/

相关文章:

python - Genfromtxt 抛出异常 "got 3 columns instead of 27"但事实并非如此

python - 使用 Homebrew 软件为 numpy 安装 gfortran

python - 我怎样才能解决这个关于Python迭代的练习?

python - 将一个数据框附加到另一个具有相同列的数据框的右侧

python - 无法通过覆盖 __new__ 创建新的对象实例

python - 如何在图像中找到区域最大值/最小值?

python - 将 numpy 矩阵转换为 pandas 数据帧或逐行序列

python - 使用基类处理 django 中的异常

python - Python 是线程安全的吗?

python - Python Flask Web 服务中带有回调的长异步计算