包装课程 [英] Wrapping classes

查看:98
本文介绍了包装课程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能实现某种懒惰的方式。使用对象时只创建对象

,但行为方式与对象相同?


例如:

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屋!

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