python-使用元类&对象实例中的类属性
我有许多继承常见的类。我需要父级来跟踪在班级级别定义的一堆依赖关系/关系。类似:
class Meta(type):
ALLDEPENDENCIES = {}
def __new__(meta, name, bases, attrs):
if "DEPENDENCIES" in attrs.keys():
for key, value in attrs.items():
if key == "DEPENDENCIES":
meta.ALLDEPENDENCIES.update(attrs["DEPENDENCIES"])
return type.__new__(meta, name, bases, attrs)
class DataTable(DataFrameWrapper, metaclass=Meta):
pass
class Foo(DataTable):
DEPENDENCIES = {"a":1}
class Bar(DataTable):
DEPENDENCIES = {"b":2}
从本质上讲,当我创建新类(Foo,bar,baz ...)时,每个类都有一个字典。我需要合并每个字典中的信息。因此,我正在使用元类,如上所示。每个类都是一个依赖性属性,我将所有这些属性收集到Metaclass中定义的Alldsptions属性中。
如果我这样做,它似乎可以很好地工作:
import Foo, Bar
print(Foo.ALLDEPENDENCIES)
>> {"a":1, "b":2}
print(Bar.ALLDEPENDENCIES)
>> {"a":1, "b":2}
但是,如果OBJ实例工作时,则缺少Alldspiensies属性:
f = Foo()
b = Bar()
print(f.ALLDEPENDENCIES)
print(b.ALLDEPENDENCIES)
属性错误 - 没有alldependencies。
我认为在元素中定义的类属性可以从self.myattibute访问,就像依赖关系一样。我在做什么错?
I have a number of classes that inherit a common one. I need the parent class to keep track of a bunch of dependencies/relationships that are defined at the class level. Something like:
class Meta(type):
ALLDEPENDENCIES = {}
def __new__(meta, name, bases, attrs):
if "DEPENDENCIES" in attrs.keys():
for key, value in attrs.items():
if key == "DEPENDENCIES":
meta.ALLDEPENDENCIES.update(attrs["DEPENDENCIES"])
return type.__new__(meta, name, bases, attrs)
class DataTable(DataFrameWrapper, metaclass=Meta):
pass
class Foo(DataTable):
DEPENDENCIES = {"a":1}
class Bar(DataTable):
DEPENDENCIES = {"b":2}
So essentially, as I create new classes (Foo, Bar, Baz...) each of them has a dictionary. I need to merge the info from each dictionary. So I'm using the metaclass, as shown above. Each class as an DEPENDENCIES attribute, and I'm gathering all of those into the ALLDEPENDENCIES attribute defined in the metaclass.
If I do this, it seems to work alright:
import Foo, Bar
print(Foo.ALLDEPENDENCIES)
>> {"a":1, "b":2}
print(Bar.ALLDEPENDENCIES)
>> {"a":1, "b":2}
However, when working if obj instances, the ALLDEPENDENCIES attributes is missing:
f = Foo()
b = Bar()
print(f.ALLDEPENDENCIES)
print(b.ALLDEPENDENCIES)
Attribute error - there is no ALLDEPENDENCIES.
I thought that the class attribute defined in the metaclass would be accessible from self.myattribute in the instances, just like DEPENDENCIES is. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Meta描述
如何创建类,而不是
什么将是什么。meta
!=带有继承属性的父
,因此您必须将适当的属性传递到新类中:
Meta describes
how
to create class but notwhat
class that will be.Meta
!=Parent
with inherited attributesSo you have to pass proper attributes into new class:
实例类属性搜索不会进入元类 - 仅进入类。 Metaclass可以在每个新类中设置
alldspertancies
,其__新__ __
中的一行,但是如果您想要清洁器代码,则在某种意义上,词典并不是任何地方,您无处不在,您只需通过课程访问属性即可。使用您的代码,如:
将从任何地方使用(就像`type(foo())。
为了在新类中设置属性,以便在新创建的类中可以看到它,一个选项是:(
在调用
type .__新的__ new __
之前,将新的attr插入attrs中插入attrs中)。在这里,我做了另外两个附加功能:(1)调用
super().__新__
,而不是对type .__新的__
的调用,这允许您的Metaclass与其他Metaclasse综合,如果您的一个类将与其他元素段交叉(例如,如果您使用abc
collections.abc ),则可能需要这一点。 (2)使用Mappingproxytype,该图是“仅读”字典视图,并将通过类或实例停止dict的交流直接更新。Instance class attribute search does not go into the metaclass - just to the class. The metaclass could set
ALLDEPENDANCIES
in each new class, with a single line in its__new__
, but if you want cleaner code, in the sense the dictionary is not aliased everywhere, you can just access the attribute through the class.Using your code, as is:
will work from anywhere (just as `type(Foo()).ALLDEPENDANCIES).
In order to set the attribute in the new classes, so that it will be visible in the newly created classes, an option is:
(Inserting the new attr in attrs before calling
type.__new__
will also work)Here I do two other extras: (1) call
super().__new__
instead of hardcoding a call totype.__new__
: this allows your metaclass to be composable with other metaclasses, which might be needed if one of your classes will cross with other metaclass (for example, if you are using abstract base classes fromabc
orcollections.abc
). And (2) using a MappingProxyType which is a "read only" dictionary view, and will stop acidental direct updates of the dict through classes or instances.