如何在python元编程中使用实例方法?
How to use instance methods in python meta programming?
我有一个 class A
:
class A(object):
a = 'a'
def __init__(self):
self.b = 'b'
def foo(self):
print A.a
print self.b
我只是想知道如何通过元编程构造这个class。
我试过:
def Init(self):
self.b = 'b'
def Foo(self):
print A_CLASS.a
print self.b
A_CLASS = type('A_CLASS',(object,),{'a':'a','__init__':Init,'foo':Foo})
myObj = A_CLASS()
myObj.foo()
可以,但是还是有问题,就是我必须用A_CLASS
作为class的名字,如果我用B_CLASS
,就不行继续工作:
B_CLASS = type('A_CLASS',(object,),{'a':'a','__init__':Init,'foo':Foo})
myObj = B_CLASS()
myObj.foo() #Error ocurred
如果有一种方法可以构造这样一个 class,其中变量的名称 'X_CLASS' 根本不相关?
问题是您在 Foo
中按字面意思使用了名称 A_CLASS
。您始终可以使用 self.__class__
.
获取当前对象的运行时 class
def Foo(self):
print self.__class__.a
print self.b
您的错误发生是因为 Foo
无条件引用 A_CLASS
,但您将 class 绑定到全局名称 B_CLASS
。在其他情况下这将是一个问题(pickle
依赖于 class 名称与其在定义模块中绑定的名称相匹配),但对于这种有限的情况,它是可以修复的。不要直接引用 A_CLASS.a
,而是用 self
:
来引用它
def Foo(self):
print self.a
print self.b
如果不存在该名称的实例属性,self
将查找 class 属性。如果您想 100% 确定它来自 class,而不是实例,您可以将其定义为:
def Foo(self):
# New-style class only, but safe against weirdness like redefining __class__
print type(self).a
# Old-style class, and vast majority of non-pathological new-style classes
print self.__class__.a
print self.b
查找 class,然后从 class 获取属性,绕过实例属性。
在继承层次结构中,这可能是错误的。如果 A_CHILD
class 具有不同的 a
class 属性,则对其调用 Foo
将获得 child 的属性。但这是违反规则的代价;如果你给一个 class 名称 A_CLASS
并将它绑定到名称 B_CLASS
,你不能通过名称 A_CLASS
来引用它进行查找(因为没有具有该绑定的程序的一部分)。
我有一个 class A
:
class A(object):
a = 'a'
def __init__(self):
self.b = 'b'
def foo(self):
print A.a
print self.b
我只是想知道如何通过元编程构造这个class。
我试过:
def Init(self):
self.b = 'b'
def Foo(self):
print A_CLASS.a
print self.b
A_CLASS = type('A_CLASS',(object,),{'a':'a','__init__':Init,'foo':Foo})
myObj = A_CLASS()
myObj.foo()
可以,但是还是有问题,就是我必须用A_CLASS
作为class的名字,如果我用B_CLASS
,就不行继续工作:
B_CLASS = type('A_CLASS',(object,),{'a':'a','__init__':Init,'foo':Foo})
myObj = B_CLASS()
myObj.foo() #Error ocurred
如果有一种方法可以构造这样一个 class,其中变量的名称 'X_CLASS' 根本不相关?
问题是您在 Foo
中按字面意思使用了名称 A_CLASS
。您始终可以使用 self.__class__
.
def Foo(self):
print self.__class__.a
print self.b
您的错误发生是因为 Foo
无条件引用 A_CLASS
,但您将 class 绑定到全局名称 B_CLASS
。在其他情况下这将是一个问题(pickle
依赖于 class 名称与其在定义模块中绑定的名称相匹配),但对于这种有限的情况,它是可以修复的。不要直接引用 A_CLASS.a
,而是用 self
:
def Foo(self):
print self.a
print self.b
如果不存在该名称的实例属性,self
将查找 class 属性。如果您想 100% 确定它来自 class,而不是实例,您可以将其定义为:
def Foo(self):
# New-style class only, but safe against weirdness like redefining __class__
print type(self).a
# Old-style class, and vast majority of non-pathological new-style classes
print self.__class__.a
print self.b
查找 class,然后从 class 获取属性,绕过实例属性。
在继承层次结构中,这可能是错误的。如果 A_CHILD
class 具有不同的 a
class 属性,则对其调用 Foo
将获得 child 的属性。但这是违反规则的代价;如果你给一个 class 名称 A_CLASS
并将它绑定到名称 B_CLASS
,你不能通过名称 A_CLASS
来引用它进行查找(因为没有具有该绑定的程序的一部分)。