码迷,mamicode.com
首页 > 其他好文 > 详细

面向对象学习(四)

时间:2019-03-05 18:36:58      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:静态   参数   调用   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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!