您的位置:首页 > 编程语言 > Python开发

2.1.7 Python中一些特殊属性和方法

2018-04-02 13:21 555 查看
在Python一些类中,通常能看到用双画线“__”开头和结尾的属性和方法,总归为特殊属性。他和我们自己所写的非"__"开头和结尾的属性方法有一些区别。1,__dict__>>> class test(object): print "这是个测试"
这是个测试>>> t = test()>>> dir(t)['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']用dir()能够查看类的属性和方法,所以在列出的结果中,都是以“__”开头和结尾的,这些都是所谓的特殊属性和方法。>>> class GoTest(object): gogo = "This is Test"
>>> GoTest.__dict__dict_proxy({'gogo': 'This is Test', '__dict__': <attribute '__dict__' of 'GoTest' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'GoTest' objects>, '__doc__': None})从现实的结果中可以发现,有一个键“gogo ”,它是这个类的属性;其值就是类属性的数据。>>> GoTest.__dict__['gogo']'This is Test'>>> GoTest.gogo'This is Test'GoTest.__dict__['gogo']意思是访问类属性,这是看到上述结果为字典类型而想到的;另外一个我们熟悉的方式就是通过点号,也一样能够实现同样的效果。2,__slots____slots__有一个非常重要的作用:优化内存使用。在某些程序当作,优化内存是非常有用和必要的。>>> class TestSlots(object): __slots__ = ("hello","world")
>>> dir(TestSlots)['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'hello', 'world']看看dir()的结果,没有有__dict__属性了;>>> TestSlots.__slots__('hello', 'world')>>> t = TestSlots()>>> t.__slots__('hello', 'world')实例化之后,实例的__slots__与类的完全一样>>> t.hello = "zhangsan">>> TestSlots.hello = "lisi">>> t.hello = "zhangsan"
Traceback (most recent call last): File "<pyshell#34>", line 1, in <module> t.hello = "zhangsan"AttributeError: 'TestSlots' object attribute 'hello' is read-only报错信息中显示tree这个属性是只读的,不能修改。>>> class TestSlots1(object): __slots__ = ("hello","world")
>>> t = TestSlots1()>>> t.world = "gaga">>> t.world'gaga'>>> TestSlots1.world<member 'world' of 'TestSlots1' objects>实例属性的值并没有传回到类属性,你也可以理解为新建立了一个同名的实例属性。__slots__已经把实例属性牢牢地管控了起来,但更本质的是优化了内存。这种优化在有大量实例的情况下效果才显著。3,__getattr__、__setattr__等__setattr__(self,name,value):如果要给name赋值,就调用这个方法。__getattr__(self,name):如果name被访问,同时它不存在,此方法被调用。__getattribute__(self,name):当name被访问时自动被调用(注意:这个仅能用于新式类),无论name是否存在,都要被调用。__delattr__(self,name):如果要删除name,这个方法就被调用。>>> class A(object): print "111"
111>>> a = A()>>> a.x
Traceback (most recent call last): File "<pyshell#59>", line 1, in <module> a.xAttributeError: 'A' object has no attribute 'x'x不是实例的成员(“成员”笼统指类的属性和方法),用a.x访问一定会报错>>> class A(object): def __getattr__(self, name): print "You use getattr" def __setattr__(self, name, value): print "You use setattr" self.__dict__[name] = value
>>> a = A()>>> a.xYou use getattr依然调用了不存在的属性a.x,按照正常例子是要报错的。但是,由于在这里使用了__getattr__(self,name)方法,当发现x不存在于对象的__dict__中时,就调用了__getattr__“拦截成员”。>>> a.x = "hello"You use setattr>>> a.x'hello'给对象的属性赋值时,调用了__setattr__(self,name,value)方法,这个方法中有一句self.__dict__[name]=value,通过这个语句,就将属性和数据保存到了对象的__dict__中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息