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