包装课程 [英] Wrapping classes
问题描述
是否有可能实现某种懒惰的方式。使用对象时只创建对象
,但行为方式与对象相同?
例如:
>
class Foo:
def __init __(self,val):
"""这真的很慢。"""
self.num = val
#这不叫Foo .__ init__还
a = lazyclass(Foo,6)
#Foo只在这里被宣布
打印a.num
我真正想做的是制作一个看起来像numarray的对象,
但是只在第一次使用它时计算它的内容。
谢谢
Jeremy
Jeremy Sanders写道:是否有可能实现某种懒惰?仅在对象使用时创建对象,但行为与对象的行为方式相同?
例如:
类Foo:
def __init __(self,val):
"""这真的很慢。""
self.num = val
#thisn''不要打电话给Foo .__ init__
a = lazyclass(Foo,6)
#Foo只在这里被宣布
打印a.num
什么我真的想做的是制作一个看起来像numarray的对象,
但只在第一次使用时计算它的内容。
几乎任何东西都是可能在Python中,尽管底层
设计理念是否合理是一个完全不同的问题。 (翻译:
尝试以下伪代码,但我怀疑是否
你在做什么是个好主意。:-))
class lazyclass(object):
''''''应该叫做lazyobject虽然......''''''
def __init __(self,class_,* args,** kwargs):
self.class_ = class_
self.args = args
self.kwargs = kwargs
self.obj =无
def _getnum(个体经营):
if self.obj是无:
self.obj = self.class _(* args,** kwargs)
返回self.obj.num
num = property(_getnum)
现在应该确实完全按照你上面要求的那样做,虽然它只是支持一个属性名称,但显然非常有限,即使__init__方法有点概括。我没有尝试
测试代码所以可能会出现错别字。
-Peter
< blockquote> Jeremy Sanders写道:
是否有可能实现某种懒惰?仅在使用对象时创建对象,但行为方式与对象相同?
通用方法将覆盖__getattribute__以使其执行
__init__方法对未初始化的对象。这是一个使用
元类的情况,因为偶数__init__方法必须被特别重写为
注册参数为懒惰的初始化。
可能你想微调触发(指定哪个属性
应该让它发生),因为每次查找都会触发...... br />
类NotInitializedObjects(类型):
def __init __(cls,* _):
realInit = cls .__ init __
def __newInit __(self,* pos,** key):
def _init():
realInit(self,* pos,** key)
self._init = _init
cls .__ init __ = __ newInit__
def __getattribute __(self,attr):
def getter(attr):
返回对象.__ getattribute __(self,attr)
if '_init''在getter中(''__ dict__''):
getter(''_ init'')()
del self._init
return getter(attr)
cls .__ getattribute __ = __ getattribute__
if __name __ ==''__ main__'':
class Class:
__metaclass __ = NotInitializedObjects
def __init __(self,* pos,** key):
self.initialized = True
打印''初始化'',pos,key
a = Class(''arg'',key =''key'')#一个虚假的初始化
尝试:
object .__ getattribute __(a,''initialized'')
除了AttributeError:#应该提高
print' '未初始化''
否则:
加价
尝试:
a.initialized #every look up would做,甚至打印
除了AttributeError:
raise
else:
print''initialized''
玩得开心Paolino
______________________________ _____
Yahoo!邮件:免费1GB每日消息10MB
http://mail.yahoo.it
Jeremy Sanders写道:是否有可能实现某种懒惰?仅在对象使用时创建对象,但行为与对象的行为方式相同?
闻起来像代理模式...
例如:
类Foo:
def __init __(self ,val):
"""这真的很慢。""
self.num = val
#这不称为Foo .__ init__还是
a = lazyclass(Foo,6)
#Foo只在这里被宣传
打印a.num
我真正想要的是什么做一个看起来像numarray的对象,
但只在第一次使用时计算它的内容。
这里是Q& D ,愚蠢的简单,可能有缺陷的解决方案:
类LazyProxy(对象):
def __init __(self,klass,* args,** kwargs):
self .__ klass = klass
self .__ args = args
self .__ kwargs = kwargs
self .__ subject = None
def __lazy_init(个体经营):
如果自我.__主题为无:
self .__ subject = self .__ klass(* self .__ args ,**自我.__ kwargs)
def _ _getattr __(self,name):
self .__ lazy_init()
返回getattr(self .__ subject,name)
def __setattr __(自我,名字,价值):
#TODO:有更好的方法来做到这一点,
#但我现在不记得它了
#没时间搜索...
如果名字在[''_LazyProxy__klass'',
''_LazyProxy__args' ',
''_ LazyProxy__kwargs'',
''_ LazyProxy__subject'']:
self .__ dict __ [name] = value
else:
self .__ lazy_init()
setattr(self .__ subject,name,value)
if __name__ == ''__main__'':
class Greeter(对象):
def __init __(self,name):
self.name = name
def greet(self,who):
return" hello%s,my name is%s" %(who,self.name)
lazy1 = LazyProxy(Greeter,''toto'')
print lazy1.greet(''titi'' )
lazy2 = LazyProxy(Greeter,''lolo'')
lazy2.name =" lili"
打印lazy2.greet(lazy1.name)
每个评论,修复等欢迎。
现在可能有更好的方法来玩这个装饰者或
元课程。
-
bruno desthuilliers
python -c" ;打印''@''。join([''。''。join([w [:: - 1] for w in p.split(''。'')])
p in''o **** @ xiludom.gro''split(''@'')])"
Is it possible to implement some sort of "lazy" creation of objects only
when the object is used, but behaving in the same way as the object?
For instance:
class Foo:
def __init__(self, val):
"""This is really slow."""
self.num = val
# this doesn''t call Foo.__init__ yet
a = lazyclass(Foo, 6)
# Foo is only initalised here
print a.num
What I really want to do is make an object which looks like a numarray,
but only computes its contents the first time it is used.
Thanks
Jeremy
Jeremy Sanders wrote:Is it possible to implement some sort of "lazy" creation of objects only
when the object is used, but behaving in the same way as the object?
For instance:
class Foo:
def __init__(self, val):
"""This is really slow."""
self.num = val
# this doesn''t call Foo.__init__ yet
a = lazyclass(Foo, 6)
# Foo is only initalised here
print a.num
What I really want to do is make an object which looks like a numarray,
but only computes its contents the first time it is used.
Almost anything is possible in Python, though whether the underlying
design idea is sound is a completely different question. (Translation:
try the following pseudo-code, but I have my suspicions about whether
what you''re doing is a good idea. :-) )
class lazyclass(object):
''''''should probably be called lazyobject though...''''''
def __init__(self, class_, *args, **kwargs):
self.class_ = class_
self.args = args
self.kwargs = kwargs
self.obj = None
def _getnum(self):
if self.obj is None:
self.obj = self.class_(*args, **kwargs)
return self.obj.num
num = property(_getnum)
Now that "should" do precisely what you''ve asked for above, though it is
obviously very limited in supporting only a single attribute name even
though the __init__ method is somewhat generalized. I didn''t try
testing the code so there could be typos.
-Peter
Jeremy Sanders wrote:Is it possible to implement some sort of "lazy" creation of objects only
when the object is used, but behaving in the same way as the object?
A generic approach would override __getattribute__ to let it perform the
__init__ method on not initialized objects.This is a case for using
metaclasses as even __init__ method must be overridden ad hoc to
register the arguments for the lazy initialization.
Probably you want to fine-tune the triggering (specifing which attribute
should make it happen ),as every look up would trigger.....
class NotInitializedObjects(type):
def __init__(cls,*_):
realInit=cls.__init__
def __newInit__(self,*pos,**key):
def _init():
realInit(self,*pos,**key)
self._init=_init
cls.__init__=__newInit__
def __getattribute__(self,attr):
def getter(attr):
return object.__getattribute__(self,attr)
if ''_init'' in getter(''__dict__''):
getter(''_init'')()
del self._init
return getter(attr)
cls.__getattribute__=__getattribute__
if __name__==''__main__'':
class Class:
__metaclass__=NotInitializedObjects
def __init__(self,*pos,**key):
self.initialized=True
print ''initializing with'',pos,key
a=Class(''arg'',key=''key'') # a fake initialization
try:
object.__getattribute__(a,''initialized'')
except AttributeError: # should raise
print ''not initialized''
else:
raise
try:
a.initialized #every look up would do ,even a print
except AttributeError:
raise
else:
print ''initialized''
Have fun Paolino
___________________________________
Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB
http://mail.yahoo.it
Jeremy Sanders wrote:Is it possible to implement some sort of "lazy" creation of objects only
when the object is used, but behaving in the same way as the object?
Smells like a Proxy pattern...
For instance:
class Foo:
def __init__(self, val):
"""This is really slow."""
self.num = val
# this doesn''t call Foo.__init__ yet
a = lazyclass(Foo, 6)
# Foo is only initalised here
print a.num
What I really want to do is make an object which looks like a numarray,
but only computes its contents the first time it is used.
Here''s a Q&D, stupid simple, possibly flawed solution:
class LazyProxy(object):
def __init__(self, klass, *args, **kwargs):
self.__klass = klass
self.__args = args
self.__kwargs = kwargs
self.__subject = None
def __lazy_init(self):
if self.__subject is None:
self.__subject = self.__klass(*self.__args,**self.__kwargs)
def __getattr__(self, name):
self.__lazy_init()
return getattr(self.__subject, name)
def __setattr__(self, name, value):
# TODO : there''s a better way to do this,
# but I don''t remember it ruight now and
# don''t have time to search...
if name in [''_LazyProxy__klass'',
''_LazyProxy__args'',
''_LazyProxy__kwargs'',
''_LazyProxy__subject'']:
self.__dict__[name] = value
else:
self.__lazy_init()
setattr(self.__subject, name, value)
if __name__ == ''__main__'':
class Greeter(object):
def __init__(self, name):
self.name = name
def greet(self, who):
return "hello %s, my name is %s" % (who, self.name)
lazy1 = LazyProxy(Greeter, ''toto'')
print lazy1.greet(''titi'')
lazy2 = LazyProxy(Greeter, ''lolo'')
lazy2.name = "lili"
print lazy2.greet(lazy1.name)
Every comment, fix etc welcome.
Now there are probably better ways to do this playing with decorators or
meta-classes.
--
bruno desthuilliers
python -c "print ''@''.join([''.''.join([w[::-1] for w in p.split(''.'')]) for
p in ''o****@xiludom.gro''.split(''@'')])"
这篇关于包装课程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!