构造,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__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()