【问题标题】:Can I use a dictionary to call methods from different classes that inheritate from the same class?我可以使用字典来调用从同一类继承的不同类的方法吗?
【发布时间】:2019-08-18 08:28:40
【问题描述】:

我有两个继承自同一个基类的类,它们有一些共同的方法(实际上是属性)。我需要这样做:

输入:一个 int 和一个来自任一类的对象;

输出:对应类的方法之一(由int确定)的结果。

我想我可以使用字典来做到这一点,如下代码:

        class ChangeInt(object):
            def bar(self, i):
                print(i)
        class PlusOne(ChangeInt):
            def bar(self, i):
                print(i+1)
        class PlusTwo(ChangeInt):
            def bar(self, i):
                print(i+2)
        methods_dict = {0:ChangeInt.bar}
        print(methods_dict[0](PlusOne(), 0))
        print(methods_dict[0](PlusTwo(), 0))

我希望输出是 1,2,但实际上我得到了这个:

0
None
0
None

我想知道这些结果是如何产生的,我应该怎么做才能修复它。提前致谢。


我完全搞乱了评论中的格式,所以我将它粘贴在这里。 感谢Dynamic Method Call In Python 2.7 using strings of method names 的 Ryan Haining,我找到了另一种方法:

        class ChangeInt(object):
            def bar(self, i):
                print(i)
        class PlusOne(ChangeInt):
            def bar(self, i):
                print(i+1)
        class PlusTwo(ChangeInt):
            def bar(self, i):
                print(i+2)
        methods_dict = {0:'bar'}
        getattr(PlusOne(), methods_dict[0])(0)
        getattr(PlusTwo(), methods_dict[0])(0)

【问题讨论】:

    标签: python-2.7


    【解决方案1】:

    这可能不是最好的方法,但它会产生预期的结果:

    class ChangeInt(object):
        def bar(self, i):
            if not ('ChangeInt' in str(self.__class__)):
                self.bar(i)
            else:
                print(i)
    class PlusOne(ChangeInt):
        def bar(self, i):
            print(i+1)
    class PlusTwo(ChangeInt):
        def bar(self, i):
            print(i+2)
    
    methods_dict = {0:ChangeInt.bar}
    
    methods_dict[0](ChangeInt(), 0)
    methods_dict[0](PlusOne(), 0)
    methods_dict[0](PlusTwo(), 0)
    

    并打印:

    0
    1
    2
    

    基类中的bar() 函数调用与给定self 实例或基类实现关联的方法,如果它是基类本身的实例(仅print(i))。这很重要,没有它,如果您在基类上调用 self.bar(i) 代码将无限调用它(即,直到它达到最大允许递归调用数)。

    检查if not ('ChangeInt' in str(self.__class__)): 是必要的,因为issubclass 也会为父类返回True

    issubclass(class, classinfo)

    如果类是子类,则返回 true (直接、间接或虚拟)类信息。一个类被认为是 自身的子类。 classinfo 可能是类对象的元组,在 在这种情况下,将检查 classinfo 中的每个条目。在任何其他 在这种情况下,会引发 TypeError 异常。

    重点是区分基类/父类和任何子类。

    最后,由于您的函数调用没有显式返回任何内容,它们实际上返回NoneNone 是您在附加打印中包含调用时要打印的内容,

    print(methods_dict[0](PlusOne(), 0))
    

    我删除了多余的打印,因此您只打印(假设的)预期内容。

    【讨论】:

    • 非常感谢。所以问题是,由于我在methods_dict 中明确写了ChangeInt.bar,它总是会调用ChangeInt 类的bar 方法,即使我将一个属于ChangeInt 子类的对象传递给它。那正确吗?如果是这样,有没有办法在methods_dict中说“继承自ChangeInt的任何类的bar方法”?
    • 嘿兄弟,我有另一种方法可以做到这一点,感谢stackoverflow.com/questions/17734618/…的Ryan Haining。``` class ChangeInt(object): def bar(self, i): print(i)类 PlusOne(ChangeInt): def bar(self, i): print(i+1) class PlusTwo(ChangeInt): def bar(self, i): print(i+2) methods_dict = {0:'bar'} getattr (PlusOne(), methods_dict[0])(0) getattr(PlusTwo(), methods_dict[0])(0)```
    • @Zhu 好的,我现在明白了,我想知道你为什么想要这种设计,它不是最健康的:) 我会保留我的答案,因为它有效,但其他方法似乎好多了.在我看来,您似乎总是在调用 ChangeInt 方法,这就是从代码中看到的样子。但我对 python 类的了解并不那么清楚,这是一个非常不标准的案例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多