1、问题由来
有一次在类的定义时将一个方法外的属性前加上了self
class Myclass(object):
self.test='hello' #错误使用self
def __init__(self, x):
self.x = x
c1 = Myclass(11)
运行时报错:
Traceback (most recent call last):
File "e:\Job\TSC\CodeCloud\classTest.py", line 40, in
class Myclass(object):
File "e:\Job\TSC\CodeCloud\classTest.py", line 41, in Myclass
self.test='hello'
NameError: name 'self' is not defined
刚开始分析是因为类在初始化时尚未执行__init__( )函数,实例对象尚未建立起来,因此这么定义会出错。但是发现__init__(self, x )函数中以及传入了self这个变量,说明实例已经创建。那么Python中实例是什么时候创建的呢?
2、Python中类的实例化过程
Python中存在着一种静态的__new__()方法,通常在定义类时不会重写__new__()方法,于是Python在调用类时会自动寻找该类的继承对象(本例中为Object),然后返回当前类的实例对象:
def __new__(cls, *args, **kwargs):
...
return object.__new__(cls) #执行object的__new__()函数
执行object的__new__()函数后会返回实例对象(self),然后将self作为第一个参数传给该类的初始化方法__init__()方法。这里self只是实例对象的一个名字,也是Python里约定俗成的一种叫法,可以自定义其名称。
当运行c1 = Myclass(11)代码时其实做了两个动作:
class Myclass(object):
def __init__(self, x):
self.x = x
c1 = Myclass(11) #相当于隐式执行了__new__()和__init()
c2 = Myclass.__new__(Myclass, 12) #显式调用__new__(),返回c2对象
c2.__init__( 12) #显示调用__init(),完成c2的初始化
print c1.x, c2.x
执行结果为:
11 12
3、解决问题
了解对象的实例化后过程后可知在__init__()方法之前使用self是不允许的,可将test变量定义成类的属性,这样即可通过类也可以通过实例访问test变量。
class Myclass(object):
test='hello'
def __init__(self, x):
self.x = x
c1 = Myclass(11) #实例化
print Myclass.test, c1.test
hello hello #输出
4、__init__( )与C++中的构造函数
C++中构造函数的作用初始化对象的数据成员,该类实例对象被创建时,编译系统为对象分配内存空间,并自动调用该构造函数,由构造函数完成成员的初始化工作。Python解释器先使用类方法__new__( )为类分配空间,返回类实例,之后通过调用该对象的__init__( )方法初始化变量。
__init__( ) | 构造函数 | |
功能 | 初始化类变量 | 初始化类变量 |
返回值 | 没有 | 没有 |
重载 | 可以,子类调使用super.__init__()重载 | 可以 |
5、单例实现方法
单例就是说一个class只能有一个instance,实现的方法有很多种。
a、重新定义__new__方法(经典做法,支持多线程操作)
class Singleton(object):
_instance = None
def __new__(cls, *args, **kw):
'''object将__new__()方法定义为静态方法,并且至少需要传递一个参数cls
cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供
'''
if not cls._instance:
print 'create Singleton instance'
cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) #super函数干啥的。。
else:
print 'instance Singleton exists'
return cls._instance
class A(Singleton):
_instance = None
def __new__(cls,*args,**kw):
if not cls._instance:
print 'create A instance'
cls._instance = super(A, cls).__new__(cls, *args, **kw)
else:
print 'instance A exists'
return cls._instance
def __init__(self):
print 'A'
A1=A()
A2=A()
输出为:
create A instance #执行A的__new__函数
create Singleton instance #执行Singleton的__new__函数
A
instance A exists
A
b、使用装饰器
def Singleton(cls):
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
print 'create instance'
_instance[cls] = cls(*args, **kargs)
else:
print 'instance exits'
return _instance[cls]
return _singleton
@Singleton
class A(object):
def __init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)
输出为:
creat instance
instance exits