我只是试图简化我的一个类,并引入了一些与flyweight设计模式相同风格的功能。
然而,我有点困惑,为什么__init__总是在__new__之后被调用。我没想到会这样。有人能告诉我为什么会发生这种情况,我如何才能实现这个功能吗?(除了将实现放在__new__中,这感觉相当粗糙。)
这里有一个例子:
class A(object):
_dict = dict()
def __new__(cls):
if 'key' in A._dict:
print "EXISTS"
return A._dict['key']
else:
print "NEW"
return super(A, cls).__new__(cls)
def __init__(self):
print "INIT"
A._dict['key'] = self
print ""
a1 = A()
a2 = A()
a3 = A()
输出:
NEW
INIT
EXISTS
INIT
EXISTS
INIT
Why?
One should look at __init__ as a simple constructor in traditional OO languages. For example, if you are familiar with Java or C++, the constructor is passed a pointer to its own instance implicitly. In the case of Java, it is the this variable. If one were to inspect the byte code generated for Java, one would notice two calls. The first call is to an "new" method, and then next call is to the init method (which is the actual call to the user defined constructor). This two step process enables creation of the actual instance before calling the constructor method of the class which is just another method of that instance.
现在,在Python中,__new__是一个用户可以访问的附加功能。由于Java的类型化特性,它没有提供这种灵活性。如果一种语言提供了这种功能,那么__new__的实现者可以在返回实例之前在该方法中做很多事情,包括在某些情况下为不相关的对象创建一个全新的实例。而且,这种方法也适用于Python中的不可变类型。
我知道这个问题很老了,但我也遇到过类似的问题。
以下是我想要的:
class Agent(object):
_agents = dict()
def __new__(cls, *p):
number = p[0]
if not number in cls._agents:
cls._agents[number] = object.__new__(cls)
return cls._agents[number]
def __init__(self, number):
self.number = number
def __eq__(self, rhs):
return self.number == rhs.number
Agent("a") is Agent("a") == True
我使用这个页面作为资源http://infohost.nmt.edu/tcc/help/pubs/python/web/new-new-method.html
One should look at __init__ as a simple constructor in traditional OO languages. For example, if you are familiar with Java or C++, the constructor is passed a pointer to its own instance implicitly. In the case of Java, it is the this variable. If one were to inspect the byte code generated for Java, one would notice two calls. The first call is to an "new" method, and then next call is to the init method (which is the actual call to the user defined constructor). This two step process enables creation of the actual instance before calling the constructor method of the class which is just another method of that instance.
现在,在Python中,__new__是一个用户可以访问的附加功能。由于Java的类型化特性,它没有提供这种灵活性。如果一种语言提供了这种功能,那么__new__的实现者可以在返回实例之前在该方法中做很多事情,包括在某些情况下为不相关的对象创建一个全新的实例。而且,这种方法也适用于Python中的不可变类型。
__new__是静态类方法,而__init__是实例方法。
__new__必须先创建实例,所以__init__可以初始化它。注意,__init__以self作为参数。在你创造实例之前,没有自我。
现在,我猜想,您正在尝试用Python实现单例模式。有几种方法可以做到这一点。
此外,从Python 2.6开始,您可以使用类装饰器。
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
...