多个Python类继承

2024-02-03

我试图理解 python 类继承方法,但在弄清楚如何执行以下操作时遇到了一些麻烦:

如何从类继承方法有条件的取决于孩子的输入?

我尝试了下面的代码但没有取得太大成功。

class A(object):
    def __init__(self, path):
        self.path = path

    def something(self):
        print("Function %s" % self.path)   


class B(object):
    def __init__(self, path):
        self.path = path
        self.c = 'something'

    def something(self):
        print('%s function with %s' % (self.path, self.c))


class C(A, B):
    def __init__(self, path):
        # super(C, self).__init__(path)

        if path=='A':
            A.__init__(self, path)
        if path=='B':
            B.__init__(self, path)
        print('class: %s' % self.path)


if __name__ == '__main__':
    C('A')
    out = C('B')
    out.something()

我得到以下输出:

class: A
class: B
Function B

虽然我想看到:

class: A
class: B
B function with something

我猜原因是A.something()使用(而不是B.something())与Python的MRO有关。


Calling __init__任何一个父类都不会改变类的继承结构,不会。除了更改之外,您仅更改运行的初始化程序方法C.__init__当创建实例时。C继承自两者A and B,以及所有方法B被那些在A由于继承顺序。

如果您需要根据构造函数中的值更改类继承,请创建两个单独的班级,具有不同的结构。然后提供不同的可调用对象作为 API 来创建实例:

class CA(A):
    # just inherit __init__, no need to override

class CB(B):
    # just inherit __init__, no need to override

def C(path):
    # create an instance of a class based on the value of path
    class_map = {'A': CA, 'B': CB}
    return class_map[path](path)

您的 API 的用户仍然有名字C()打电话;C('A')生成一个不同类的实例C('B'),但它们都实现相同的接口,因此这对调用者来说并不重要。

If you have有一个通用的“C”类可以使用isinstance() or issubclass()测试,你可以混合其中之一,然后使用__new__ method https://docs.python.org/3/reference/datamodel.html#object.__new__覆盖返回的子类:

class C:
    def __new__(cls, path):
        if cls is not C:
            # for inherited classes, not C itself
            return super().__new__(cls)
        class_map = {'A': CA, 'B': CB}
        cls = class_map[path]
        # this is a subclass of C, so __init__ will be called on it
        return cls.__new__(cls, path)

class CA(C, A):
    # just inherit __init__, no need to override
    pass

class CB(C, B):
    # just inherit __init__, no need to override
    pass

__new__被调用来构造新的实例对象;如果__new__方法返回该类(或其子类)的实例,然后__init__将自动在该新实例对象上调用。这就是为什么C.__new__()返回结果CA.__new__() or CB.__new__(); __init__我们将会为您打电话。

后者的演示:

>>> C('A').something()
Function A
>>> C('B').something()
B function with something
>>> isinstance(C('A'), C)
True
>>> isinstance(C('B'), C)
True
>>> isinstance(C('A'), A)
True
>>> isinstance(C('A'), B)
False

如果这些选项都不适合您的特定用例,则必须在新的中添加更多路由somemethod()实施于C,然后调用A.something(self) or B.something(self)基于self.path。当你必须这样做时,这很快就会变得很麻烦每一个方法,但是装饰器可以提供帮助:

from functools import wraps

def pathrouted(f):
    @wraps
    def wrapped(self, *args, **kwargs):
        # call the wrapped version first, ignore return value, in case this
        # sets self.path or has other side effects
        f(self, *args, **kwargs)
        # then pick the class from the MRO as named by path, and call the
        # original version
        cls = next(c for c in type(self).__mro__ if c.__name__ == self.path)
        return getattr(cls, f.__name__)(self, *args, **kwargs)
    return wrapped

然后在类的空方法上使用它:

class C(A, B):
    @pathrouted
    def __init__(self, path):
        self.path = path
        # either A.__init__ or B.__init__ will be called next

    @pathrouted
    def something(self):
        pass  # doesn't matter, A.something or B.something is called too

然而,这变得非常不Python且丑陋。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多个Python类继承 的相关文章

随机推荐

  • 用冒号对数字进行排序

    我有一个圣经经文 时间或其他一些带有数字和冒号的字符串的列表 我希望将这些分类为 1 5 2 1 2 8 2 14 11 36 我将如何对这些数字进行排序 我假设我必须解析字符串 用冒号分隔 然后排序 我尝试过的给了我这样的东西 1 5 1
  • 使用 'with_items' 时,Ansible 显示错误:“一个或多个未定义的变量:'item' 未定义”

    我正在尝试计算 elb 内的实例数 这是我的 Ansible 剧本 name Get elb facts local action module ec2 elb facts name elb region ansible ec2 place
  • Xcode 服务器 CI Bot 测试会话已退出 (-1)

    尝试在 XcodeServer 上针对模拟器设备运行测试时出现错误 有时 一台设备的测试通过 另一台设备的测试失败 但失败的设备并不总是同一台设备 这可以在单个会话中发生 日志文件错误如下 2015 03 23 10 44 11 029 I
  • jQuery.ajax() - 如何最好地处理超时?

    我想知道 处理超时的最佳方法是什么jQuery ajax 这是我目前的解决方案 如果发生超时 页面将被重新加载 并且脚本将有另一个机会在给定的时间范围内加载数据 Problem 如果 get json php 下面的示例 确实不可用 它将成
  • 从自定义 mojo 访问 Maven 插件运行时配置的最佳方法?

    我正在编写一个自定义的 maven2 MOJO 我需要从此 MOJO 访问另一个插件的运行时配置 做这个的最好方式是什么 您可以使用以下步骤获取当前在构建中使用的插件列表 首先 您需要让 Maven 将当前项目注入到您的 mojo 中 您可
  • 如何摆脱算法的复杂性?

    锻炼 编写一个 multiple a b 函数 将数字 a 乘以数字 b 而不使用 运算符或 Math imul 方法 multiple 1 1 1 multiple 1 2 2 multiple 0 0 0 Code export def
  • 如何使用两条相交线的概念在 Netlogo 中实现避障(海龟标题与由补丁组成的墙)

    我们如何将 Netlogo 海龟的方向转换为直线方程 y mx c 以便可以将其与另一个直线方程 例如代表墙的补丁 进行比较 我需要将乌龟的航向转换为直线方程 然后将标题线方程与墙的线方程进行比较 墙的线方程有固定的 x 或固定的 y 取决
  • python中读取资源文件

    我是一名 Java 开发人员 后来转为 Python 开发人员 如何在python中读取类路径资源文件 这是我的目录结构 resources test schema xml create confd serialized objects s
  • 以编程方式发送短信,无需打开消息应用程序

    到目前为止 我正在使用以下代码通过我的应用程序向另一部手机发送短信 Intent intent new Intent Intent ACTION VIEW Uri parse sms srcNumber intent putExtra sm
  • 在 Swift 中录制音频

    有谁知道我在哪里可以找到有关如何在 Swift 应用程序中录制音频的信息 我一直在查看一些音频播放示例 但似乎无法找到有关实现音频录制的任何内容 谢谢 在 Swift 3 中 添加框架AVFoundation 在info plist中添加键
  • 使用复选框 onClick 覆盖父级 onClick 事件?

    首先 抱歉我的英语不好 我正在创建一个优惠券网站 但在选择和取消选择优惠券时遇到问题 每张优惠券都位于一个 DIV 框 中 其中有一个复选框 我在 DIV 框中创建了一个 onClick 函数 这样用户可以通过单击 DIV 框中的任何内容来
  • 设置不带货币符号的货币格式

    我在用NumberFormat getCurrencyInstance myLocale 获取我给定的区域设置的自定义货币格式 但是 这始终包含我不想要的货币符号 我只想为给定的区域设置提供正确的货币数字格式 而无需货币符号 Doing a
  • Objective C 中的惰性数据类型

    在 SML 中 可以采用以下方式对惰性编程进行建模 Have a datatype to wrap a computation datatype a susp Susp of unit gt a A function to hold the
  • chol.default(K) 中出现错误:5 阶前导小数对于 betareg 不是正定的

    我正在尝试适应一个beta regression模型使用betareg function of the betareg package对这些数据 df lt data frame category c c1 c1 c1 c1 c1 c1 c
  • 使用 C# 以编程方式读取 Openoffice Calc (.ods)?

    我想知道是否可以使用 C 以编程方式读取 OpenOffice Calc 电子表格 我可以对 Excel xls 和 xlsx 执行此操作 但无法找到读取计算电子表格的解决方案 如果有人有解决方案 请帮助我 ODF NET http www
  • python将csv数据发送到spark Streaming

    我想尝试在 python 中加载 csv 数据并通过 SPark Streaming 流式传输每一行 Spark 我对网络东西还很陌生 我不完全是如果我应该创建一个服务器 python 脚本 一旦建立连接 使用 Spark 流 它将开始发送
  • 在 Spring Boot 中使用 Keycloak 实现 JWT、JWE 和 JWS(签名 JWT)

    我尝试使用 Spring Boot 和 Keycloak 作为 AuthService 来实现一个简单的 OAuth2 使用签名 JWT 进行客户端身份验证 演示应用程序 这个想法是 one secured REST service The
  • 等待和通知如何工作?

    我需要知道 wait 和 notification 到底是如何工作的 我无法通过使用 wait 和 notification 来实现其工作 相反 如果我使用 while 循环等待 它就会正常工作 怎么会这样呢 为什么我不能简单地使用 wai
  • 寻找许可证密钥算法[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Stack Overflow 上有很多与许可证密钥相关的问题 但他们不回答这个问题 任何人都可以提供一个简单的许可证密钥算法 该算法独
  • 多个Python类继承

    我试图理解 python 类继承方法 但在弄清楚如何执行以下操作时遇到了一些麻烦 如何从类继承方法有条件的取决于孩子的输入 我尝试了下面的代码但没有取得太大成功 class A object def init self path self