Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使类方法识别它运行在哪个类上下文中_Python - Fatal编程技术网

Python 使类方法识别它运行在哪个类上下文中

Python 使类方法识别它运行在哪个类上下文中,python,Python,我需要重构现有的代码,方法是将一个复制粘贴在各个类之间的方法折叠成一个方法,这些类彼此继承。 因此,我生成了以下代码: class A(object): def rec(self): return 1 class B(A): def rec(self): return self.rec_gen(B) def rec_gen(self, rec_class): return super(rec_class, self).r

我需要重构现有的代码,方法是将一个复制粘贴在各个类之间的方法折叠成一个方法,这些类彼此继承。 因此,我生成了以下代码:

class A(object):
    def rec(self):
        return 1

class B(A):
    def rec(self):
        return self.rec_gen(B)

    def rec_gen(self, rec_class):
        return super(rec_class, self).rec() + 1

class C(B):
    def rec(self):
        return self.rec_gen(C)

if __name__=='__main__':
    b = B(); c = C()
    print c.rec()
    print b.rec()
以及输出:

3
2

仍然困扰我的是,在“rec”方法中,我需要告诉“rec_gen”它所运行的类的上下文。“rec_gen”是否有办法在运行时自行解决此问题?

此功能已添加到Python 3中-请参阅。简言之:

class B(A):
    def rec(self):
        return super().rec() + 1
我认为您创建了复杂的rec/rec_gen设置,因为您无法自动找到该类,但如果您希望这样做,以下操作应该可以:

class A(object):
    def rec(self):
        return 1

class B(A):
    def rec(self):
        # __class__ is a cell that is only created if super() is in the method
        super()
        return self.rec_gen(__class__)

    def rec_gen(self, rec_class):
        return super(rec_class, self).rec() + 1

class C(B):
    def rec(self):
        # __class__ is a cell that is only created if super() is in the method
        super()
        return self.rec_gen(__class__)
Python 2中最简单的解决方案是使用私有成员来保存超级对象:

但这仍然需要在一个位置指定实际的类,如果在类层次结构中碰巧有两个同名的类(例如来自不同的模块),此方法将中断

在PEP3135出现之前,我们中有几个人为Python 2制定了自动解析的方法——我的方法是。基本上,它允许以下内容:

class B(A, autosuper):
    def rec(self):
        return self.super().rec() + 1
或者在使用相同名称调用父方法的情况下,最常见的情况是:

class B(A, autosuper):
    def rec(self):
        return self.super() + 1
此方法的注意事项:

相当慢。我有一个版本在某处进行字节码操作,以大大提高速度

它与PEP3135不一致,尽管它曾经是Python3Super的一个提案

这很复杂

这是基类的混合


我不知道上述是否能满足您的要求。通过对配方的一个小改动,您可以找到您所处的类并将其传递给rec_gen-基本上是将类查找代码从_getSuper提取到它自己的方法中。

我不确定您到底想要实现什么,但是如果只是有一个方法为每个类返回不同的常量值,那么就使用类属性来存储该值。从你的例子中根本不清楚你需要去超级附近的任何地方


python 2.x的另一种解决方案是使用元类在所有子类中自动定义rec方法:

class RecGen(type):
    def __new__(cls, name, bases, dct):
        new_cls = super(RecGen, cls).__new__(cls, name, bases, dct)

        if bases != (object,):
            def rec(self):
                return super(new_cls, self).rec() + 1
            new_cls.rec = rec

        return new_cls

class A(object):
    __metaclass__ = RecGen
    def rec(self):
        return 1

class B(A):
    pass

class C(B):
    pass
请注意,如果您只是想获得类似父类的数量,那么使用self会更容易

class A(object):
    def rec(self):
        return len(self.__class__.__mro__)-1

class B(A):
    pass

class C(B):
    pass

我不确定你想做什么,但我相信你可以从self那里得到这个类。这是不可能的,因为self。self总是有调用类,所以如果我调用c.rec,self.\uuuuu class.\uuuuu name.\uuuuuu将始终是'C'@monkut这样做可能会导致无限递归-self.\uuuuu class.\uuuuuu始终是对象的实际类,而不是定义了当前所用方法的类。self.\uuu class.\uuuuu就是您所需要的。
class RecGen(type):
    def __new__(cls, name, bases, dct):
        new_cls = super(RecGen, cls).__new__(cls, name, bases, dct)

        if bases != (object,):
            def rec(self):
                return super(new_cls, self).rec() + 1
            new_cls.rec = rec

        return new_cls

class A(object):
    __metaclass__ = RecGen
    def rec(self):
        return 1

class B(A):
    pass

class C(B):
    pass
class A(object):
    def rec(self):
        return len(self.__class__.__mro__)-1

class B(A):
    pass

class C(B):
    pass