Python 创建类对象实例的过程

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

猜你喜欢

转载自blog.csdn.net/u012474535/article/details/80018369