标签:静态 参数 调用 one for循环 删除 对象产生 直接 工作
运算符重写
#encoding=utf-8
class Vector(object):
def __init__(self,a,b):
self.a = a
self.b = b
def __str__(self):
return "Vector(%d,%d)" %(self.a,self.b)
def __add__(self,other):
return Vector(self.a + other.a,self.b + other.b)
x = Vector(3,7)
y = Vector(1,-10)
print(x + y)
print(str(x))
类的特殊成员
1.__doc__
类的描述信息
#encoding=utf-8
class Vector(object):
"""类的描述信息"""
def __init__(self):
pass
v = Vector()
print(v.__doc__)
2. __module__ 和 __class__
? __module__ 表示当前操作的对象在那个模块
? __class__ 表示当前操作的对象的类是什么
3.__del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
>>> class P():
... def __del__(self):
... print("del exe")
...
>>> p = P()
>>> del p
del exe
4. __call__
对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于
__call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
#encoding=utf-8
class Foo(object):
def __init__(self):
pass
def __call__(self,*args,**kwargs):
print("__call__")
obj = Foo()
obj()#会调用实例的__call__方法
5. __dict__
类或对象中的所有成员
6. __str__
如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
>>> class Foo(object):
... def __str__(self):
... return "__str__被调用"
...
>>> obj = Foo()
>>> print(obj)
__str__被调用
7. __getitem__ 、__setitem__ 、__delitem__
用于索引操作,如字典。以上分别表示获取、设置、删除数据
#encoding=utf-8
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‘] = ‘kkkk‘#自动调用 __setitem__
del obj["k1"]#自动调用 __delitem__
8. __getslice__、__setslice__、__delslice__ 在python 2.7可以使用,在3.x已经被去掉了,需要使用__getitem__、__setitem__、__delitem__和__getslice__来实现
#encoding=utf-8
class Foo(object):
def __init__(self,name,age):
self.name = name
self.age = age
self.li = [1,2,3,4,5,6,7]
def __getitem__(self,item):
if isinstance(item,slice):
return self.li[item]
elif isinstance(item,int):
return self.li[item]
def __setitem__(self,key,value):
print(key,value)
self.li[key] =value
def __delitem__(self,key):
print(key)
del self.li[key]
a = Foo("alex",18)
print(a[3:5])#自动调用__getitem__
a[0] = 100#自动调用__setitem__
print(a[0])#自动调用__getitem__
del a[0]#自动调用__delitem__
print(a[0])#自动调用__getitem__
9.__iter__
用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内
部定义了 __iter__
#encoding=utf-8
class Foo(object):
def __init__(self,sq):
self.sq = sq
def __iter__(self):
return iter(self.sq)
obj = Foo([1,2,3,4,5])
for i in obj:
print(i)
10.__slot__
限制实例可以使用的属性名称
#encoding=utf-8
class Student(object):
__slots__ =("name","age")# 用tuple定义允许绑定的属性名称
s = Student()
s.name = "hhh"
s.age = 25
s.score = 99
11. __new__
__new__() 方法是在类准备将自身实例化时调用。
__new__() 方法始终都是类的静态方法,即使没有被加上静态方法装饰器。
#encoding=utf-8
class A(object):
def __init__(self):
print("init")
def __new__(cls,*args,**kwargs):
print("new %s" %cls)
return object.__new__(cls,*args,**kwargs)
A()
结果分析:
首先调用__new__()方法实例化类,产生类的实例对象;
然后实例对象调用__init__()方法;
继承自object的新式类才有__new__。
__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供。
__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例。
__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值。若__new__没有正确返回 当前类 cls的实例,那__init__是不会被调用的,即使是父类的实例也不行。
__new__ 、 __init__区别
__new__() 类实例化时候调用,产生类的实例
__init__() 类实例对象产生后调用,用来初始化对象的数据
单例
#encoding=utf-8
class Singleton(object):
def __new__(cls,*args,**kwargs):
if not hasattr(cls,"_instance"):
orig = super(Singleton,cls)
cls._instance = orig.__new__(cls,*args,**kwargs)
return cls._instance
class MyClass(Singleton):
a = 1
one = MyClass()
two = MyClass()#one 和 two 完全相同
two.a = 3
print(one.a)
print(id(one))
print(id(two))
print(one == two)
print(one is two)
python对象销毁(垃圾回收)
同Java语言一样,Python使用了引用计数这一简单技术来追踪内存中的对象。在Python内部记录着所有使用中的对象各有多少引用。一个内部跟踪变量,称为一个引用计数器。当对象被创建时,就创建了一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0 时,它被垃圾回收。但是回收不是"立即"的,由解释器在适当的时机,将垃圾对象占用的内存空间回收
>>> import sys
>>> print(sys.getrefcount(8787))
3
>>> a = 8787
>>> print(sys.getrefcount(a))
2
>>> b = a
>>> print(sys.getrefcount(a))
3
>>> c = a
>>> print(sys.getrefcount(a))
4
>>> d = c
>>> print(sys.getrefcount(a))
5
>>> [1,2].append(a)
>>> print(sys.getrefcount(a))
5
>>> del d
>>> print(sys.getrefcount(a))
4
>>> del b
>>> print(sys.getrefcount(a))
3
>>> del a
>>> print(sys.getrefcount(a))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name ‘a‘ is not defined
垃圾回收
垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充,垃圾收集器也会留心被分配的总量很大(及未通过引用计数销毁的那些)的对象。在这种情况下,解释器会暂停下来,试图清理所有未引用的循环。析构函数 __del__ ,__del__在对象销毁的时候被调用,当对象不再被使用时,__del__方法运行:
#encoding=utf-8
class Point(object):
def __init__(self,x=0,y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print(class_name,"销毁")
pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1),id(pt2),id(pt3))
del pt1
print(pt2)
print(pt3)
del pt2
print(pt3)
del pt3
print(pt3)
循环引用的对象被销毁
#encoding=utf-8
class LeakTest(object):
def __init__(self):
self.a = None
self.b = None
print("object = %d born here" %id(self))
A = LeakTest()
B = LeakTest()
A.a = B
B.b = A
import sys
print(sys.getrefcount(A))
print(sys.getrefcount(B))
del A
try:
print(sys.getrefcount(A))
except Exception as e:
print(e)
del B
try:
print(sys.getrefcount(B))
except Exception as e:
print(e)
标签:静态 参数 调用 one for循环 删除 对象产生 直接 工作
原文地址:https://blog.51cto.com/13496943/2358554