我可以为Python中的继承方法创建别名吗?

2024-10-01 02:25:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python程序中有一个相当复杂的类层次结构。这个程序有许多工具,它们不是模拟器就是编译器。这两种类型共享一些方法,因此有一个Shared类作为所有类的基类。下面的示例如下所示:

class Shared:
  __TOOL__ = None

  def _Prepare(self):
    print("Preparing {0}".format(self.__TOOL__))


class Compiler(Shared):
  def _Prepare(self):
    print("do stuff 1")
    super()._Prepare()
    print("do stuff 2")

  def _PrepareCompiler(self):
    print("do stuff 3")
    self._Prepare()
    print("do stuff 4")


class Simulator(Shared):
  def _PrepareSimulator(self):   # <=== how to create an alias here?
    self._Prepare()           


class Tool1(Simulator):
  __TOOL__ = "Tool1"

  def __init__(self):
    self._PrepareSimulator()

  def _PrepareSimulator(self):
    print("do stuff a")
    super()._PrepareSimulator()
    print("do stuff b")

我可以将方法Simulator._PrepareSimulator定义为Simulator/Shared._Prepare的别名吗?在

我知道我可以创建本地别名,比如:__str__ = __repr__,但是在我的例子中,_Prepare在上下文中是未知的。我没有self也没有cls来引用这个方法。在

我可以编写一个decorator来返回_Prepare而不是{}?但是我如何在装饰器中找到_Prepare?在

我也需要调整方法绑定吗?在


Tags: 方法self程序deftoolpreparedoclass
1条回答
网友
1楼 · 发布于 2024-10-01 02:25:20

我设法创建了一个基于decorator的解决方案,它可以确保类型安全。第一个修饰符将别名注释到本地方法。需要保护别名目标。需要第二个修饰符来替换Alias实例,并检查别名是否指向类型层次结构中的方法。在

装饰器/别名定义:

from inspect import getmro

class Alias:
  def __init__(self, method):
    self.method = method

  def __call__(self, func):
    return self

def HasAliases(cls):
  def _inspect(memberName, target):
    for base in getmro(cls):
      if target.__name__ in base.__dict__:
        if (target is base.__dict__[target.__name__]):
          setattr(cls, memberName, target)
          return
      else:
        raise NameError("Alias references a method '{0}', which is not part of the class hierarchy: {1}.".format(
          target.__name__, " -> ".join([base.__name__ for base in getmro(cls)])
        ))

  for memberName, alias in cls.__dict__.items():
    if isinstance(alias, Alias):
      _inspect(memberName, alias.method)

  return cls

用法示例:

^{pr2}$

@Alias(Shared._Prepare)设置为@Alias(Shared2._Prepare)将引发异常:

NameError: Alias references a method '_Prepare', which is not part of the class hierarchy: Simulator -> Shared -> object.

相关问题 更多 >