如何获取当前类对象的引用?
在Python中,如何在类语句中获取对当前类对象的引用?例如:我已经注销如何获取当前类对象的引用?
def setup_class_members(cls, prefix): setattr(cls, prefix+"_var1", "hello") setattr(cls, prefix+"_var2", "goodbye") class myclass(object): setup_class_members(cls, "coffee") # How to get "cls"? def mytest(self): print(self.coffee_var1) print(self.coffee_var2) x = myclass() x.mytest() >>> hello >>> goodbye
替代品有:
使用
locals()
:这给出了可以写入到一个类声明的字典。这似乎适用于类,但文档告诉你不要这样做。 (如果有人能向我保证这会继续工作一段时间,我可能会试着采用这种方法)。在
class
声明之后向类对象添加成员:我的实际应用是派生一个PyQt4QWidget
类具有动态创建的pyqtProperty
类属性。QWidget
是不寻常的,因为它有一个自定义的元类。非常粗略地说,元类编译一个pyqtProperties
的列表并将其存储为额外的成员。因此,创建后添加到类中的属性不起作用。一个例子来清除此设置:
from PyQt4 import QtCore, QtGui # works class MyWidget1(QtGui.QWidget): myproperty = QtCore.pyqtProperty(int) # doesn't work because QWidget's metaclass doesn't get to "compile" myproperty class MyWidget2(QtGui.QWidget): pass MyWidget2.myproperty = QtCore.pyqtProperty(int)
请注意,以上将用于大多数编程情况下工作;我的情况恰好是这些不寻常的角落案件之一。
AFAIK有两路做你想要什么:
-
使用metaclass,这将创造一流的创建时间的两个变量(我认为这是你想要的):
class Meta(type): def __new__(mcs, name, bases, attr): prefix = attr.get("prefix") if prefix: attr[prefix+"_var1"] = "hello" attr[prefix+"_var2"] = "goodbye" return type.__new__(mcs, name, bases, attr) class myclass(object): __metaclass__ = Meta prefix = "coffee" def mytest(self): print(self.coffee_var1) print(self.coffee_var2)
-
在实例化时创建你的两个类变量:
MyClass类(对象): PREFIX = “咖啡”
def __init__(self): setattr(self.__class__, self.prefix+"_var1", "hello") setattr(self.__class__, self.prefix+"_var2", "goodbye") def mytest(self): print(self.coffee_var1) print(self.coffee_var2)
N.B:我不知道你想达到的,因为如果你要取决于prefix
变量为什么你喜欢访问你在mytest
方法做,以创建动态的变量是什么?!我希望这只是一个例子。
我不知道为什么代码的格式不为我工作?! – mouad
是的,例子很傻。这个解决方案看起来很有希我没有提到我使用的Python 3似乎有不同的元类支持。计算出现在的差异...... – goertzenator
对于Python 3,类必须被声明为
class myclass(object, metaclass = Meta):
prefix = "coffee"
...
其他一些要点:
元类可以是一个可调用的,而不是仅仅一个类(Python的2 & 3)
如果基类的类已经有一个非标准元类,你必须确保你怎么称呼它是
__init__()
和__new__()
方法,而不是类型的。类语句接受被传递给元类关键字参数(Python的3只)
使用所有上述是在Python 3 mouad的解决方案的一个重写...
def MetaFun(name, bases, attr, prefix=None):
if prefix:
attr[prefix+"_var1"] = "hello"
attr[prefix+"_var2"] = "goodbye"
return object.__class__(name, bases, attr)
class myclass(object, metaclass = MetaFun, prefix="coffee"):
def mytest(self):
print(self.coffee_var1)
print(self.coffee_var2)
+1,用于将我最初的答案移植到python 3中,并教给我元类可以是任何可调用的(我不知道),顺便说一句,我们应该称之为“元类函数或元函数;-),除此之外,如果我可能还有一些说法(问题):1.如果您正在为python 3编写代码,则不需要从'object'明确地继承'class myclass(metaclass =为什么你要调用'object .__ class__'而不是'type(...)'这当然是一样的,但我更喜欢最新的只是想知道:) – mouad
@mouad:你是对的,我可以把'object'当作基础类。 2.在我的实际应用中,基类('PyQt4.QtGui.QWidget')的元类有* not *'type',当我使用'type'时给我一个错误。通过使用'object .__ class__',我正在说明如何检索实际的基类元类。 – goertzenator
您可能使用的另外两种方法:
类装饰器。
def setup_class_members(prefix):
def decorator(cls):
setattr(cls, prefix+"_var1", "hello")
setattr(cls, prefix+"_var2", "goodbye")
return cls
return decorator
@setup_class_members("coffee")
class myclass(object):
# ... etc
特别是如果你需要在不同的组合中添加属性,因为它没有继承任何作用的装饰方法是很好的。
如果你正在处理一个小套的,你想以各种方式相结合的属性,你可以使用混入类。 mixin类是一个普通类,它只是为了将各种属性“混合”到其他类中。
class coffee_mixin(object):
coffee_var1 = "hello"
coffee_var2 = "goodbye"
class tea_mixin(object):
tea_var1 = "good morning old bean"
tea_var2 = "pip pip cheerio"
class myclass(coffee_mixin, tea_mixin):
# ... etc
+1,对于装饰者的方法,为什么我没有考虑它:) – mouad
mouad的答案绝对是一个必须解决的问题,但要描述发生了什么:类定义只是在它自己的本地范围内执行一系列语句。一旦完成后,类名,基类的列表,并且将所得的dict当地人被传递到[类型构造](http://docs.python.org/library/functions.html#type)为'类型( class_name,bases_tuple,locals_dict),然后返回'cls'。因此,'cls'在你想要的位置不可用,只有在之后。此外,使用元类将导致它被调用来代替'type',并且具有相同的签名。 –
我不知道这事'当地人()'把戏班工作。有趣的一点琐事。 :-) – kindall