1

I would like to do something like this:

class A:
    def hello(): print "Hello"

# I do not want to explicitly setup a:
a = A()

# a = A() -> I want this to happen automatically when I access a
# My first try is this:
def a():
    return A()

# Also, I do not want to call a as a function a(): it must be an object
# And it must stay alive and initialized
a.hello() # a is created, as object of class A
a.hello() # I do not want a second instantiation

How can I implement this? properties? cached-properties? They are only for classes: a is a module-level object.

4

3 回答 3

3

也许是这样的:

class A(object):
    def hello(self):
        print "Hello"

class LazyA(object):
    def __init__(self):
        self.instance = None

    def __getattr__(self, k):
        if self.instance is None:
            self.instance = A()

        return getattr(self.instance, k)

a = LazyA()
于 2013-04-25T10:15:23.877 回答
1
def lazyinit(cls):

    class p(object):
        def __init__(self, *args, **kws):
            self._init = lambda: cls(*args, **kws)            
            self._obj  = None

        def __getattr__(self, k):
            if not self._obj:
                self._obj = self._init()
            return getattr(self._obj, k)

    return p

例子:

@lazyinit
class A(object):
    def __init__(self, a, b):
        print("initializing...")
        self.x = a + b + 2

    def foo(self):
        return self.x

x = A(39, 1)
print x
print x.foo()
print x.foo()
于 2013-04-25T13:05:02.493 回答
0

Pavel 对答案的概括:

class LazyClass(object):

    def __init__(self, myclass, *args, **kwargs):
        self.instance = None
        self.myclass = myclass
        self.args = args
        self.kwargs = kwargs

    def __getattr__(self, k):
        if self.instance is None:
            self.instance = self.myclass(*self.args, **self.kwargs)

        return getattr(self.instance, k)

class A(object):

    def __init__ (self, name):
        self.name = name
        print "Created"

    def hello(self):
        print "Hello " + self.name

import unittest
class TestLazyClass(unittest.TestCase):

    def setUp(self):
        self.a = LazyClass(A, 'Daniel')

    def test_it(self):
        self.a.hello()
        self.a.hello()
于 2013-04-25T10:40:19.140 回答