构造,new对象

import time
class A:
    def __init__(self):
        self.f = open('userinfo','a')
    def con(self):
        pass
    def __del__(self):
        '''
    析构方法,当对象在内存中被释放时,自动触发执行。
    注:此方法一般无须定义,因为Python是一门高级语言,
    程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,
    析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
        :return:
        '''
        self.f.close()
        print('删除一个对象的时候调用')
    #在删除一个对象之前做的一些工作
a = A()
time.sleep(2)
del a
# 在删除一个对象的时候,如果内部存在__del__d方法
# 那么在删除要给udix之前先执行__del__方法中的代码
print(a)  #现在再打印提示没有a这个对象

# __new__(),new一个对象

class H:
    def __init__(self):
        print('执行了init方法')
    def __new__(cls):
        print('执行了new方法')
        return object.__new__(cls) #创建对象,将对象返回
h=H()
print(type(h))
print(type(H))
# # 先执行了__new__()方法后创造了一个对象
# # 然后把创造出来的对象传递给__init__方法
# # 会把self自动的返回,然后被h接受

元类 #有一个元类,在创建类 #ype() 
#所有直接用class创建出来的类的元类都是type

__new__ 和 __metaclass__:
class Foo(object):

    def __init__(self):

        pass

obj = Foo()   # obj是通过Foo类实例化的对象
上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,
因为在Python中一切事物都是对象


如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,
那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

1.print type(obj) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建

 

2.print type(obj) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建

 

所以,obj对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

那么,创建类就可以有两种方式:

 

a). 普通方式:

class Foo(object):

 

    def func(self):

        print 'hello hei'

 

b).特殊方式(type类的构造函数)

 

def func(self):

    print 'hello wupeiqi'

Foo = type('Foo',(object,), {'func': func})

#type第一个参数:类名

#type第二个参数:当前类的基类

#type第三个参数:类的成员

 

==》 类 是由 type 类实例化产生

那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,

从而查看 类 创建的过程。

 

#单例设计模式 
#在一个类中可以被多次实例化 但是同时在python的内存中,只能有一个实例

 

class Li:
    _instance = None  #创造了要给为空的实例
    def __init__(self,name):
        '给娃穿衣服'
        self.name = name
    def __new__(cls, *args, **kwargs):
        if not Li._instance:  #如果_instance 非空的话
            Li._instance = object.__new__(cls) #就给_instance,__new一个新对象
        return Li._instance   #最后把这个对象返回回去
al =Li('alex')  # 第一次实例化的时候创造一个实例
print(al.name)   #第一次打出来的是'alex'
a2 = Li('欣欣')  #此时是第二次实例化新的实例化把之前的覆盖了
print(a2.name)   #所以此时al.name 已经也成了a2实例化的值

print(al.name, a2.name)  #此时输出了 2次 欣欣

#如果并发量大的话,内存里就会存在非常多功能上一模一样的对象。存在这些对象肯定会消耗内存, 
#对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用,也是极好的

单例2:

class Foo:
    name = 'alex'
    @classmethod
    def func(cls):
        pass
Foo.name = 'sb'
print(Foo.name)

Foo.age = 'hello'
print(Foo.age)

print(Foo.name,Foo.age)

 

##################item系列###############

 例一:

class W:
    '''
    默认初始化动态方法__init__
    '''
    def __init__(self,name):
        self.name = name
        self.age = 18

    def __getitem__(self, item):
        return self.__dict__[item]

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):  #删除tiem这个方法
        del self.__dict__[key]
w = W('猴子') # 给W类的init添加一个实例化
print(w['name']) # getitem 通过getitem方法调用w这个对象以字典方式查看['name']
print(w.name)   #__init通过init对象初始化调用w的实例
print(w['age']) #__getiem对应了类中一个方法

#增加 和修改一个属性通过__setitem
w['sex'] ='男的'
print(w.__dict__)  #查看w对象这个里面的所有属性以字典方式表现出
        #输出结果:=={'name': '猴子', 'age': 18, 'sex': '男的'}

w['job'] ='大保健' #在w这个对象中再添加一个键值对'job':'大保健'
print(w.__dict__)
        #输出结果:=={'name': '猴子', 'age': 18, 'sex': '男的', 'job': '大保健'}


del w['sex']  #'sex'属性不幸被删除
print(w.__dict__) #现在查

 

例二: 

__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据。
class Foo(object):

    def __getitem__(self, key):

        print '__getitem__',key
def __setitem__(self, key, value): print '__setitem__',key,value def __delitem__(self, key): print '__delitem__',key obj = Foo() result = obj['k1'] # 自动触发执行 __getitem__ obj['k2'] = 'wupeiqi' # 自动触发执行 __setitem__
del obj['k1'] # 自动触发执行 __delitem__

 

##############__dic__()方法#################

类或对象中的所有成员

上文中我们知道:类的普通字段属于对象;类中的静态字段和方法等属于类

 

class Province:

    country = 'China'

    def __init__(self, name, count):
        self.name = name
        self.count = count

    def func(self, *args, **kwargs):
        print 'func'

# 获取类的成员,即:静态字段、方法、
print Province.__dict__
# 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>
, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
obj1 = Province('HeBei',10000) print obj1.__dict__ # 获取 对象obj1 的成员 # 输出:{'count': 10000, 'name': 'HeBei'} obj2 = Province('HeNan', 3888) print obj2.__dict__ # 获取 对象obj1 的成员 # 输出:{'count': 3888, 'name': 'HeNan'

 ##############__str__()方法#################

如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

 

class Foo:

    def __str__(self):
        return '123'

obj = Foo()
print obj
# 输出:123i

 

 ##############___iter__ #################

用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__ 

class Foo(object):

    def __init__(self, sq):
        self.sq = sq

    def __iter__(self):
        return iter(self.sq)

obj = Foo([11,22,33,44])

for i in obj:
    print i
以上步骤可以看出,for循环迭代的其实是  iter([11,22,33,44]) ,所以执行流程可以变更为:
obj = iter([11,22,33,44]
 
for i in obj:
    print i
 

 

 

 

 ##############__call__()方法#################

class F:
    def __call__(self,a):
        print('执行了我1',a)
    def call(self,a):
        print('22',a)
f = F()
f('Av')
print(f)
f.call('aaa')
# 对象后面加括号,触发执行。
#
# #注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;
而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

 

 

 

 


 



 



posted @ 2018-03-13 21:38  胸不平$怎平天下  阅读(219)  评论(0编辑  收藏  举报