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 <module> 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): if not cls._instance: print 'create instance' cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) else: print 'instance exists' return cls._instance a1 = Singleton() a2 = Singleton()
输出为:
creat instance instance exits
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