zoukankan      html  css  js  c++  java
  • 【编程开发】Python隐藏属性——使用双下划线标识私有属性,外部不可直接访问

     

    小编在最初使用上Python之后,就一发不可收拾,人生苦短、我用Python,不光是因为其优雅简洁,更是因为它强大的扩展性,特别是一些Python内置的私有属性,熟练地掌握之后使得在开发过程中更灵活、更高效,今天小编就细数一些常用的私有属性,希望能够帮助到新手朋友们。

    Python的隐藏属性无处不在,内置的私有属性往往是双下划线开头,双下划线结尾,这里我们从模块到对象,由上往下的来列举常用的属性用法。

     

    模块属性

     

    1、__name__

    当python文件被直接运行时,__name__的值为__main__,而当python文件以模块的形式被导入时,__name__的值为模块名

    def say_hello():
        print hello
    
    if __name__ == __main__:
        say_hello()
    

    上面的代码是最为常见的__name__的使用方式,当文件中有上述代码后,直接运行脚本则会执行say_hello方法,通过import形式导入脚本文件时则不会执行say_hello。

    2、__file__

    在python模块中使用__file__来获取脚本所在的路径,但得到的是相对路径,若希望得到绝对路径可使用os.path.realpath(__file__)

     

    3、__all__

    __all__指定的是当包被import * 的时候, 哪些模块会被import进来

    #test1.py
    import os, sys
    __all__ = [os]
    
    #test2.py
    from test1 import *
    sys.path
    ImportError: No module named sys
    

    上述代码可以看出,本来导入test1模块时,os、sys也会被一并导入进来,但是__all__属性限定了只导入os,所以sys并没有被导入进来。

     

    4、__path__

    __path__指定了包的搜索路径,默认情况下只有一个元素, 就是当前包的路径, 修改__path__, 可以修改此包内的搜索路径,修改该属性类似于修改sys.path

     

    类、实例属性

     

    1、__class__

    __class__属于实例的属性,直接指向该实例的类对象

    class A(object):
    	pass
    
    a = A()
    a.__class__等同于A
    

     

    2、__dict__

    对象的属性字典,key为属性名,value为该属性的值

    注:__dict__若被实例对象引用则列出实例对象的属性,若被类引用则列出类属性

    class A():  
        def __init__(self):  
            self.x=1   #定义一个实例属性  
        y = 2          #定义一个类属性  
    
    
    a = A()
    a.__dict__
    {'x': 1}
    A.__dict__
    {'__doc__': None,
     '__init__': function __main__.__init__
     '__module__': '__main__',
     'y': 2}
    

    上述代码可以看出,实例对象a的__dict__属性只包含实例属性x,而类A的__dict__属性则包含了所有类属性

     

    3、__slots__

    __slots__限制了类中只能定义某些属性

    class Test(object):
    	__slots__ = ['a']
    
    test = Test()
    test.a = 1
    test.b = 1
    AttributeError: 'Test' object has no attribute 'b'
    

    __slots__限定了属性集只能包含'a',所以在定义属性'b'时报出错误。

     

    4、__new__、__init__

    继承自object的新式类才有__new__

    __new__在实例被创建时调用,__init__在实例创建后的初始化时调用,所以先调用__new__,然后调用__init__

    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 class '__main__.A'
    init
    

    __new__方法必须返回一个实例对象

     

    5、__del__

    相当于类的析构函数,当类对象被销毁前调用

    class MyClass(object):
    	def __del__(self):
    		print hehe
    
    a = MyClass()
    del a
    hehe
    

     

    6、操作符类属性

    __str__:str()或print时调用

    __len__:len()时调用

    __cmp__:cmp()时调用

    __lt__,__gt__,__eq__:,,=时被调用

    __add__,__sub__,__mul__,__div__:+、-、*、/时被调用

    __getitem__,__setitem__,__delitem__:列表引用、设置、删除时被调用

    这些操作符类属性是Python类的内置类方法,往往当需要重载操作符时重载相应的类方法即可。

     

    7、自定义私有属性

    在定义类属性时,若在该属性前加上__,则该属性被定义为私有属性,即该属性不可被外部直接引用,只能在类的内部使用

    class A(object):
    	
    	def __init__(self):
    		self.__a = 1
    
    	def func(self):
    		print self.__a
    
    a = A()
    a.func()
    #输出
    1
    a.__a
    #输出
    AttributeError: 'A' object has no attribute '__a'
    

    然而Python对__a这个属性做了什么呢?实际上该属性并不是不存在的,当在某个属性前加上两个下划线后,python自动将其所在的类名追加在属性前导致其拥有了新的属性名,也由此实现了该属性不可引用的假象

    class A(object):
    	
    	def __init__(self):
    		self.__a = 1
    
    	def func(self):
    		print self.__a
    
    
    a = A()
    a._A__a
    #输出
    1
    

     

    好了,我们就讨论到这里,关于Python更多的编程技巧、知识我们后续会继续交流,也欢迎感兴趣的朋友们私信讨论。

  • 相关阅读:
    索引覆盖与覆盖索引的深入探究
    附加数据库后,数据库状态为只读
    Starting MySQL. ERROR! The server quit without updating PID file(xxx/x.pid)
    【1.4】shell基本实践——根据文件做交互选择
    mysql中count与null的坑
    深入理解yield(二):yield与协程
    深入理解yield(三):yield与基于Tornado的异步回调
    tornado.gen 模块解析
    pip 安装指定版本的python包
    [转]Tornado get/post请求异步处理框架分析
  • 原文地址:https://www.cnblogs.com/bonelee/p/11175929.html
Copyright © 2011-2022 走看看