具有名称重载的元类。 [英] Metaclass with name overloading.

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

问题描述

我想写一个元类,它允许我在其实例的定义中重载

名称,比如这个


类Foo(对象) ):


__metaclass__ = OverloadingClass


att = 1

att = 3

def meth(self):

pass


def meth(self,arg):

return arg

我会喜欢OverloadingClass收到的字典.__ new__

看起来像这样:


{''att' ':( 1,3),

''meth :(< function meth at 0x4018e56c>,< function meth at 0x4018e80c>)}


IOW,类定义中绑定的每个名称都应该与它相关联,这是一个元组,包含绑定到该名称的所有对象,而不仅仅是保留最新的名称。绑定任何给定的

名称。


我想知道是否有可能通过

forcin来实现这个目标g Python使用一些dicitonary代理(它累积值,

而不是只保留与一个键关联的最后一个值),

而不是dict,执行时class definiton?


在纯Python中是否可以这样?或者确实在

需要摆弄周围在分析器的胆

解决方案
亚切克Generowicz< JA *** ***********@cern.ch>写道:

...

我想写一个元类,它允许我在其实例的定义中重载
名称,比如这个
...我想知道是否有可能通过强制Python使用一些dicitonary代理(它累积值,而不是只保留与键关联的最后一个值)来实现这一点),而不是dict,在执行类定义时?

纯Python中是否有这样的东西?或者在
中需要摆弄解析器的内容吗?




在纯Python中不可能 - Python总是使用真实的dict

而不是你想要的任何其他类型。解析器OTOH也不应该真的涉及
。最后它归结为一系列

STORE_NAME伪代码指令,目前正在执行:


case STORE_NAME:

w = GETITEM(姓名,oparg);

v = POP();

if((x = f-> f_locals)!= NULL){

if(PyDict_CheckExact(x))

err = PyDict_SetItem(x,w,v);

else

err = PyObject_SetItem(x ,w,v);

Py_DECREF(v);


因此他们能够使用f_locals作为dict或任何

其他映射 - 所以该部分应该没问题。但是帧f'的
f_locals只不过是一个字典,现在就是问题...

Alex


2004年9月27日13:33:33 +0200,Jacek Generowicz

< ja ************** @ cern。 CH>写道:

< snip>
然后我会喜欢OverloadingClass .__ new__
收到的字典看起来像这样:

{'' att'':( 1,3),
''meth :(< function meth at 0x4018e56c> ;,< function meth at 0x4018e80c>)}

IOW,每个名字绑定在类定义应该与它相关联,它是一个元组,包含绑定到该名称的所有对象,而不仅仅是为任何给定的名称保留最新的绑定。

我想知道是否有可能通过强制Python使用一些dicitonary代理(它累积值,而不是只保留与键关联的最后一个值)来实现这一点。 ,当执行类定义时,而不是dict?

纯Python中是否有类似的东西?或者在
中需要摆弄解析器的内容吗?




不,你不能,而且它不仅仅是一个解析器问题。 Python使用对本机dict类型的直接C

调用。这是硬编码,除了重写所有这些代码之外,我没有看到任何明显或简单的覆盖它的方法。

元类接收字典在收到所有声明之后收取了b $ b,然后采取行动为时已晚。


现在我们正在谈论它,我我想讨论一下这种类型的hack怎么可能在未来的Python版本中完成(可能是这样的,但是我觉得不是这样的。)任何接近可能的Python

2.x)。


1)其中一个想法是为元类提供一个__dict__工厂。

例如:


类MyMetaclass(类型):

def __new __(...):

。 ..

def __dict __(cls):

返回CustomDict()


....其中CustomDict是用户 - 定义的映射类型可以存储

关于条目的更多信息而不是本机字典:


- CustomDict [n ame]将检索包含所有条目的元组,在

逆序中。 CustomDict [name] [0]将检索最后一个定义。


- 将保留定义的顺序,并且迭代器

(iterkeys, iteritems,itervalues)将按照定义的顺序遍历条目




通过使用用户定义的dict,我们仍然会使用默认dict最多

的时间没有任何明显的性能损失,但是能够在需要时更改类声明系统的内容。


2)另一个(疯狂)想法是有可能宣布

匿名类成员,例如:


class MyClass :

"""所述第一匿名构件是doc字符串"""

"""所述第二匿名构件是__anon __ [0 ]"""

1.5#__onon __ [1] = 1.5


匿名成员,我的意思是任何不是def的东西,嵌套的

等级,或者a没有分配或绑定名称的值。那也是好的b / b很高兴:-)


-------

p.s.在原始海报的特殊情况下,我想知道他有什么样的应用程序。我有类似的需求,而

学习一些替代方案,以声明某些类型的数据结构在
Python中 - 表单,报告,网页等 - 其中的顺序

条目可能与实际的会员名称一样重要。

我真的好奇它...


-

Carlos Ribeiro

Consultoria em Projetos

博客: http://rascunhosrotos.blogspot.com

博客: http://pythonnotes.blogspot.com

mail: ca ******** @ gmail.com

mail: ca ******** @ yahoo.com


Carlos Ribeiro< ca ******** @ gmail。 COM>写道:

...

不,你不能,而且它不只是一个解析器问题。 Python使用对本机dict类型的直接C
调用。它是硬编码的,除了重写所有这些代码之外,我没有看到任何明显或简单的方法来覆盖它。


在类主体获得的代码对象中使用的STORE_NAME已经为该框架的非本机字典f_locals做好了准备。

问题是如何将你自己喜欢的对象放到那个f_locals

的第一个地方,而且那个很难 - 不能想到任何方式...... 。

收集完所有声明后,元类收到字典,然后对它采取行动为时已晚。


是的,太晚了。你必须以某种方式调整CALL_FUNCTION

字节码,它被编译为类语句的一部分,这样它就会产生一个f_locals有些奇怪的帧。你选择的对象。

现在我们正在谈论它,我想讨论一下这种类型的hack如何在未来的Python版本中完成(probaly < Python 3.0,我认为它几乎不可能用于Python
2.x)。


我认为它在2.5中可能是相当可行的(对于2.4来说太迟了)。


1)其中一个想法是提供元类与__dict__工厂。


如果你走那条路,那么它确实可能需要更深的变化来支付

2.5或2.anything。元类后来确定,当时

CALL_FUNCTION执行的元类还没有播放。

通过使用用户定义的dict,我们仍然会使用默认dict最多的时间没有任何明显的性能损失,但能够在需要时更改类声明系统的内容。


是的,但如果你把它变成了元类的工作,那么你确实要求

从今天的架构中做出深刻的改变。

2)另一个(疯狂的)想法是有可能宣布匿名班级成员,例如:

类MyClass:
"""所述第一匿名构件是doc字符串"""
"""所述第二匿名构件__anon __ [0]"""
1.5# __anon __ [1] = 1.5

匿名成员,我指的不是def,嵌套的
类,或者没有赋值或绑定名称的值。那也是很好的: - )




也许,也许不是,但它至少与交易无关br />
有两个同名的def',就像OP想要的那样。


有一件事可行:有一个sys._set_locals_factory(... )

允许你改变(可能是每个线程......?)帧的f_locals是如何制作的。

Alex


I would like to write a metaclass which would allow me to overload
names in the definition of its instances, like this

class Foo(object):

__metaclass__ = OverloadingClass

att = 1
att = 3

def meth(self):
pass

def meth(self, arg):
return arg
I would then like the dictionary received by OverloadingClass.__new__
to look something like this:

{''att'': (1,3),
''meth: (<function meth at 0x4018e56c>, <function meth at 0x4018e80c>) }

IOW, each name bound in the class definition should have associated
with it, a tuple containing all the objects which were bound to that
name, rather merely keeping the most recent binding for any given
name.

I was wondering whether it would be possible to achieve this by
forcing Python to use some dicitonary proxy (which accumulates values,
rather that keeping just the last value to be associated with a key),
instead of dict, when executing the class definiton?

Is something like this at all possible in pure Python? or does in
require fiddling around in the guts of the parser?

解决方案

Jacek Generowicz <ja**************@cern.ch> wrote:
...

I would like to write a metaclass which would allow me to overload
names in the definition of its instances, like this ... I was wondering whether it would be possible to achieve this by
forcing Python to use some dicitonary proxy (which accumulates values,
rather that keeping just the last value to be associated with a key),
instead of dict, when executing the class definiton?

Is something like this at all possible in pure Python? or does in
require fiddling around in the guts of the parser?



It''s not possible in pure Python -- Python will always use a real dict
rather than any other type as you''d wish. The parser OTOH shouldn''t
really be involved, either. In the end it boils down to a series of
STORE_NAME pseudocode instructions, which currently do:

case STORE_NAME:
w = GETITEM(names, oparg);
v = POP();
if ((x = f->f_locals) != NULL) {
if (PyDict_CheckExact(x))
err = PyDict_SetItem(x, w, v);
else
err = PyObject_SetItem(x, w, v);
Py_DECREF(v);

so they''d be able to work with f_locals being either a dict, or any
other mapping -- so that part should be OK. But having frame f''s
f_locals be anything but a dict, now THAT is the problem...
Alex


On 27 Sep 2004 13:33:33 +0200, Jacek Generowicz
<ja**************@cern.ch> wrote:

<snip>
I would then like the dictionary received by OverloadingClass.__new__
to look something like this:

{''att'': (1,3),
''meth: (<function meth at 0x4018e56c>, <function meth at 0x4018e80c>) }

IOW, each name bound in the class definition should have associated
with it, a tuple containing all the objects which were bound to that
name, rather merely keeping the most recent binding for any given
name.

I was wondering whether it would be possible to achieve this by
forcing Python to use some dicitonary proxy (which accumulates values,
rather that keeping just the last value to be associated with a key),
instead of dict, when executing the class definiton?

Is something like this at all possible in pure Python? or does in
require fiddling around in the guts of the parser?



No, you can''t, and it''s not just a parser issue. Python uses direct C
calls to the native dict type. It''s hard coded, and I don''t see any
obvious or easy way to override it except by rewriting all such code.
The metaclass receives the dictionary after all declarations were
collected, and then it''s too late to act upon it.

Now that we''re talking about it, I would like to discuss how this type
of hack could possibly be done in a future version of Python (probaly
Python 3.0, I don''t think it''s anywhere close to possible for Python
2.x).

1) One such idea is to provide the metaclass with a __dict__ factory.
For example:

class MyMetaclass(type):
def __new__(...):
...
def __dict__(cls):
return CustomDict()

.... where CustomDict is a user-defined mapping type that can store
more information about the entries than the native dict:

-- CustomDict[name] would retrieve a tuple containing all entries, in
reverse order. CustomDict[name][0] would retrieve the last definition.

-- The order of the definitions would be preserved, and the iterators
(iterkeys, iteritems, itervalues) would all iterate over the entries
in the order of the definition.

By using a user-defined dict, we would still use the default dict most
of the time without any noticeable performance hit, but would be able
to change the guts of the class declaration system whenever needed.

2) Another (crazy) idea is to have the possibility to declare
anonymous class members, such as in:

class MyClass:
"""the first anonymous member is the doc string"""
"""the second anonymous member is __anon__[0]"""
1.5 # __anon__[1] = 1.5

By anonymous members, I mean anything that is not a def, a nested
class, or a value that wasn''t assigned or bound to name. That''s would
be nice to have too :-)

-------
p.s. In the particular case of the original poster, I''m wondering what
kind of application did he had in mind. I had similar needs while
studying some alternatives to declare some types of data structure in
Python -- forms, reports, webpages, etc -- stuff where the order of
the entries is potentially as important than the actual member names.
I''m really curious about it...

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com


Carlos Ribeiro <ca********@gmail.com> wrote:
...

No, you can''t, and it''s not just a parser issue. Python uses direct C
calls to the native dict type. It''s hard coded, and I don''t see any
obvious or easy way to override it except by rewriting all such code.
The STORE_NAME used within the code object to which the class body gets
compiled is quite ready for a non-native-dict f_locals of the frame.
The problem is how to get your own favourite object into that f_locals
in the first place, and THAT one is hard -- can''t think of any way...
The metaclass receives the dictionary after all declarations were
collected, and then it''s too late to act upon it.
Yep, far too late. You''d have to somehow tweak the CALL_FUNCTION
bytecode that''s compiled as part of the class statement, so that it
makes a frame whose f_locals is some strange object of your choice.
Now that we''re talking about it, I would like to discuss how this type
of hack could possibly be done in a future version of Python (probaly
Python 3.0, I don''t think it''s anywhere close to possible for Python
2.x).
I think it might be quite feasible in 2.5 (too late for 2.4).

1) One such idea is to provide the metaclass with a __dict__ factory.
If you go that route, then it may indeed require changes too deep for
2.5 or 2.anything. The metaclass gets determined later, at the time
CALL_FUNCTION executes the metaclass ain''t in play yet.
By using a user-defined dict, we would still use the default dict most
of the time without any noticeable performance hit, but would be able
to change the guts of the class declaration system whenever needed.
Yeah, but if you make it a metaclass''s job, then you''re indeed asking
for deep changes from today''s architecture.
2) Another (crazy) idea is to have the possibility to declare
anonymous class members, such as in:

class MyClass:
"""the first anonymous member is the doc string"""
"""the second anonymous member is __anon__[0]"""
1.5 # __anon__[1] = 1.5

By anonymous members, I mean anything that is not a def, a nested
class, or a value that wasn''t assigned or bound to name. That''s would
be nice to have too :-)



Maybe, and maybe not, but it would not help in the least with dealing
with two def''s for the same name, as the OP wanted.

One thing that might work: have a sys._set_locals_factory(...) which
lets you change (maybe per-thread...?) how a frame''s f_locals are made.
Alex


这篇关于具有名称重载的元类。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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