在元类中订购 [英] Order in metaclass

查看:38
本文介绍了在元类中订购的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下示例中:


class MyMetaclass(type):pass

class MyBaseType(object):__ metaclass__ = MyMetaclass

class MyType(MyBaseType):

x = 4

y = 5

z = 6


有没有办法修改MyMetaclass以保持x,y,z的顺序?


Thx和问候,

Nicolas

In the following example:

class MyMetaclass(type): pass
class MyBaseType(object): __metaclass__ = MyMetaclass
class MyType(MyBaseType):
x = 4
y = 5
z = 6

Is there any way to modify MyMetaclass to keep the order of x,y,z somewhere?

Thx and regards,
Nicolas

推荐答案

2004年10月12日星期二15:37:22 -0400,Nicolas Fleury写道:
On Tue, 12 Oct 2004 15:37:22 -0400, Nicolas Fleury wrote:
在下面的示例中:

类MyMetaclass(类型):传递
类MyBaseType(对象):__ metaclass__ = MyMetaclass
类MyType(MyBaseType):
x = 4
y = 5
z = 6
有没有办法修改MyMetaclass以保持x,y,z的顺序?

感谢和问候,
In the following example:

class MyMetaclass(type): pass
class MyBaseType(object): __metaclass__ = MyMetaclass
class MyType(MyBaseType):
x = 4
y = 5
z = 6

Is there any way to modify MyMetaclass to keep the order of x,y,z somewhere?

Thx and regards,
Nicolas




什么订单?


是的,它们按特定顺序列在源代码中,但是

在该命令的六个排列之间绝对没有区别,在理论上或事实上,因为vars最终出现在一个字典中。


如果你想要一个订单的概念,你将自己定义一个

。你想做什么,究竟是什么?


我猜你试图按顺序取出vars $
迭代,这可能不对,但也延伸到其他情况

相当干净。


简单的解决方案是一个列表:


class MyClass(object):

classData = [4,5,6]

offsets = {''x'':0,'' y'':1,''z'':2}

def getVarMaker(var):

def getVar(个体经营):

return self.classData [self.offsets [var]]

return getVar

def setVarMaker(var):

def setVar(self,value ):

self.classData [self.offsets [var]] = value

返回setVar

x = property(getVarMaker(''x') '),setVarMaker('''x''))

y = property(getVarMaker(''y''),setVarMaker(''y''))

z = property(getVarMaker(''z''),setVarMaker(''z''))

def __iter __(self):

表示self.classData中的值:

屈服值


元类可以获取classData和offsets并使访问变量为

你。

--------

def getVarMaker(var):

def getVar(self):

返回self.classData [self.offsets [var]]

返回getVar


def setVarMaker(var):

def setVar(self,value):

self.classData [self.offsets [var]] = value

return setVar


class OrderedClassAttributes(type):

def __init __(cls,name,bases,dict):

super(OrderedClassAttributes,cls).__ init __(name,bases ,字典)

cls.offsets中的名字:

setattr(cls,name,property(getVarMaker(name),

setVarMaker(name) )))


class MyClass(object):

classData = [4,5,6]

offsets = {' 'x'':0,''y'':1,''z'':2}

__metaclass__ = OrderedClassAttributes

def __iter __( self):

表示self.classData中的值:

收益价值


---------

(假设上面是复制/粘贴到Python中:)



What order?

Yeah, they are listed in the source in a particular order, but there is
absolutely no difference between the six permutations of that order, in
theory or in fact, since the vars end up in a dict.

If you want a concept of "order", you''re going to have do define one
yourself. What do you want to do, exactly?

I''m going to guess you''re trying to get the vars out in order upon an
iteration, which may not be right but extends to other cases as well
fairly cleanly.

The easy solution is a list:

class MyClass(object):
classData = [4, 5, 6]
offsets = {''x'': 0, ''y'': 1, ''z'':2}
def getVarMaker(var):
def getVar(self):
return self.classData[self.offsets[var]]
return getVar
def setVarMaker(var):
def setVar(self, value):
self.classData[self.offsets[var]] = value
return setVar
x = property(getVarMaker(''x''), setVarMaker(''x''))
y = property(getVarMaker(''y''), setVarMaker(''y''))
z = property(getVarMaker(''z''), setVarMaker(''z''))
def __iter__(self):
for value in self.classData:
yield value

A metaclass could take classData and offsets and make the access vars for
you.
--------
def getVarMaker(var):
def getVar(self):
return self.classData[self.offsets[var]]
return getVar

def setVarMaker(var):
def setVar(self, value):
self.classData[self.offsets[var]] = value
return setVar

class OrderedClassAttributes(type):
def __init__(cls, name, bases, dict):
super(OrderedClassAttributes, cls).__init__(name, bases, dict)
for name in cls.offsets:
setattr(cls, name, property(getVarMaker(name),
setVarMaker(name)))

class MyClass(object):
classData = [4, 5, 6]
offsets = {''x'': 0, ''y'': 1, ''z'':2}
__metaclass__ = OrderedClassAttributes
def __iter__(self):
for value in self.classData:
yield value

---------
(Assuming the above is copy/pasted into Python:)

m = MyClass()
mx
4我的
5 mz
6 my = 33
我的
33列表(m)
m = MyClass()
m.x 4 m.y 5 m.z 6 m.y = 33
m.y 33 list(m)

< br $> b $ b [4,33,6]

---------


经过轻微测试但按照我的设计工作。


这就是你想要的吗?如果没有,请随时提出更多要求。当然还有其他选择

但没有更多数据,很难知道你需要什么。


这是一个我认为非常好的元类使用。


[4, 33, 6]
---------

Lightly tested but working as I designed.

Is that what you wanted? If not, feel free to ask more. There are
certainly other options but without more data, it is hard to know what you
need.

This is a pretty good metaclass use, I think.


Nicolas Fleury< ni ****** @ yahoo.com_remove_the_>在留言新闻中写道:< Rn ******************** @ news20.bellglobal.com> ...
Nicolas Fleury <ni******@yahoo.com_remove_the_> wrote in message news:<Rn********************@news20.bellglobal.com >...
在下面示例:

类MyMetaclass(类型):传递
类MyBaseType(object):__ metaclass__ = MyMetaclass
类MyType(MyBaseType):
x = 4
y = 5
z = 6
有没有办法修改MyMetaclass以保持x,y,z的顺序?

感谢和问候,
Nicolas
In the following example:

class MyMetaclass(type): pass
class MyBaseType(object): __metaclass__ = MyMetaclass
class MyType(MyBaseType):
x = 4
y = 5
z = 6

Is there any way to modify MyMetaclass to keep the order of x,y,z somewhere?

Thx and regards,
Nicolas




简答:不。


x,y,z在班级词典中。字典没有订单。


你可以使用类似的东西

类MyType(MyBaseType):

__mylist__ = [(x,4),(y,5),(z,6)]


并使用元类设置类属性x ,y和z为你。

Michele Simionato



Short answer: No.

x, y, z are in the class dictionary. dictionaries have no order.

You could use something like

class MyType(MyBaseType):
__mylist__ = [("x", 4), ("y", 5), ("z",6)]

and use the metaclass to set the class attributes x,y and z for you.
Michele Simionato


Nicolas Fleury写道:
Nicolas Fleury wrote:
在下面的例子:

类MyMetaclass(类型):传递
类MyBaseType(object):__ metaclass__ = MyMetaclass
类MyType(MyBaseType):
x = 4
y = 5
z = 6
有没有办法修改MyMetaclass以保持x,y,z的顺序?
In the following example:

class MyMetaclass(type): pass
class MyBaseType(object): __metaclass__ = MyMetaclass
class MyType(MyBaseType):
x = 4
y = 5
z = 6

Is there any way to modify MyMetaclass to keep the order of x,y,z
somewhere?



如果你想记录这些定义的顺序,你需要传递一个

自定义词典来跟踪班级中的作业

代码(基本上是包含类套件的普通python函数)。

不幸的是,这个字典 - 你后来看到的元类__new __()方法的分类元素

参数 - 始终是用C创建的字典,

,如最近讨​​论的那样clpy(对不起,但我记得的所有关键词都是

''metaclass''和''martelli'' - 不是很有选择性:-)。下面是我的(笨拙)

尝试解决方法:


导入itertools


类OrderedValue(对象) :

newIndex = itertools.count(1).next

def __init __(self,value):

self.value = value

self.index = self.newIndex()


class Meta(类型):

def __new __(mcl,name,bases, classdict):

断言ordered_names不在课堂上


values = []

for(n,v)in classdict.iteritems():

尝试:

v,i = v.value,v.index

除了AttributeError:

pass

else:

values.append((i,n,v))

values.sort()


ordered_names = []

for(i,n,v)的值:

ordered_names.append(n)

classdict [n] = v

classdict [" ordered_names"] = ordered_names


返回类型.__ new __(mcl,name,bases,classdict)

class Base:

__metaclass__ = Meta


类演示(基础):

alpha = 0

beta = OrderedValue(1 )

gamma = OrderedValue(17)

delta = OrderedValue(3)


打印Demo.ordered_names

打印Demo.alpha,Demo.beta

Peter



If you want to record the order of these definitions, you need to pass a
custom dictionary that keeps track of assignments in the class generation
code (basically a normal python function comprising the class suite).
Unfortunately that dictionary - which you see later as the classdict
parameter of the metaclass __new__() method - is always a dict created in C,
as was recently discussed on c.l.py (sorry, but all keywords I remember are
''metaclass'' and ''martelli'' - not very selective :-). Below is my (clumsy)
attempt for a workaround:

import itertools

class OrderedValue(object):
newIndex = itertools.count(1).next
def __init__(self, value):
self.value = value
self.index = self.newIndex()

class Meta(type):
def __new__(mcl, name, bases, classdict):
assert "ordered_names" not in classdict

values = []
for (n, v) in classdict.iteritems():
try:
v, i = v.value, v.index
except AttributeError:
pass
else:
values.append((i, n, v))
values.sort()

ordered_names = []
for (i, n, v) in values:
ordered_names.append(n)
classdict[n] = v
classdict["ordered_names"] = ordered_names

return type.__new__(mcl, name, bases, classdict)
class Base:
__metaclass__ = Meta

class Demo(Base):
alpha = 0
beta = OrderedValue(1)
gamma = OrderedValue(17)
delta = OrderedValue(3)

print Demo.ordered_names
print Demo.alpha, Demo.beta
Peter


这篇关于在元类中订购的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆