【问题标题】:Can I create a class that inherits from another class passed as an argument?我可以创建一个继承自作为参数传递的另一个类的类吗?
【发布时间】:2023-03-26 10:39:01
【问题描述】:

就像here 发布的问题一样,我想创建一个继承自作为参数传递的另一个类的类。

class A():
    def __init__(self, args):
        stuff

class B():
    def __init__(self, args):
        stuff

class C():
    def __init__(self, cls, args):
        self.inherit(cls, args)

args = #arguments to create instances of A and B
class_from_A = C(A, args) #instance of C inherited from A
class_from_B = C(B, args) #instance of C inherited from B

我想这样做,以便跟踪我对不同 Web api 的调用。我的想法是我只是将我自己的功能添加到任何 api 类型的对象中。链接问题的解决方案的问题是我不想通过额外的“层”来使用 api-type 对象。我想说obj.get_data() 而不是obj.api.get_data()

我尝试研究 super() 的工作原理,但没有发现任何有用的东西(尽管我很容易错过一些东西)。任何帮助都会很好,对于我正在尝试做的事情,我愿意接受任何其他方法,但是,出于好奇,我想知道这是否可能。

【问题讨论】:

  • 这似乎是XY problem。您可能想改用组合,就像链接的问题说的那样,尽管如何完成obj.get_data = obj.api.get_data 是另一个问题。那么,C 究竟是如何跟踪对AB 的调用的呢? AB 方法一样吗?
  • AutoEncoder有条件地继承链接问题的已接受答案中的任何内容。
  • @wjandrea 你可能是对的......如果我使用合成,你能指出我完成obj.get_data = obj.api.get_data 问题的方向吗? (坦率地说,我对继承或组合不是很熟悉)
  • @Hudson 我们首先需要你提供一些信息,我已经要求过:“C 究竟是如何跟踪对 A 和 B 的调用的?A 和 B 有吗?同样的方法?”
  • @wjandrea A 和 B 没有相同的方法。我对 C 如何跟踪调用持开放态度:我在另一条评论中提到你的权利,这是一个 XY 问题。我应该编辑这个问题还是创建一个新帖子?

标签: python python-3.x class inheritance


【解决方案1】:

我认为这是不可能的,因为 __init____new__ 之后调用,这是您指定基类的地方,但我认为您可以使用元类实现跟踪 api 调用的目标。由于您没有提供任何示例来说明跟踪调用的含义,因此我将为您提供一个计算方法调用的示例元类。您可以根据自己的需要进行调整。

另一种选择是将AB 子类化为跟踪您需要的任何方法,然后返回super().whatever()。我想我更喜欢这种方法,除非AB 包含太多值得这样管理的方法。

这是an implementation from python-course.eu,作者 Bernd Klein。点击链接了解更多详情。

class FuncCallCounter(type):
    """ A Metaclass which decorates all the methods of the 
        subclass using call_counter as the decorator
    """
    
    @staticmethod
    def call_counter(func):
        """ Decorator for counting the number of function 
            or method calls to the function or method func
        """
        def helper(*args, **kwargs):
            helper.calls += 1
            return func(*args, **kwargs)
        helper.calls = 0
        helper.__name__= func.__name__
    
        return helper
    
    
    def __new__(cls, clsname, superclasses, attributedict):
        """ Every method gets decorated with the decorator call_counter,
            which will do the actual call counting
        """
        for attr in attributedict:
            if callable(attributedict[attr]) and not attr.startswith("__"):
                attributedict[attr] = cls.call_counter(attributedict[attr])
        
        return type.__new__(cls, clsname, superclasses, attributedict)

【讨论】:

  • 阅读您的回答后,我开始意识到我应该为我的问题提供更多背景信息,正如@wjandrea 所提到的,我认为这是一个 XY 问题。我应该只是编辑我的问题还是创建一个新帖子?
  • @HudsonHochstedler 新帖
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2016-04-11
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 2014-08-26
相关资源
最近更新 更多