2018-01-24 python中的下划线使用解释

keywords: python, 下划线(underline)

一、单下划线

1. 前单下划线,如 _add()

  • 对方法名或者函数名前面加单下划线,如在script.pymodule中有def _add()函数,代表将该方法是module script私有,即在其他module中如果这样from script import *时,是无法访问_add()函数的,但是有一样一个例外:
import script
# 此时是可以访问_add()函数的
script.add()

还有一个事,你知道么
上述是否也适用于Python中的类呢

class A:
    def __init__(self):
        self._a = 1
        self.b = 2
    def ad(self):
        return self.a + self.b
    def _get_a(self):
        return 1+2
     
        
>>> class_a = A()
>>> class_a._a
1
#咦,既然能访问到看似像类私有的属性,那按上边所说看似像类私有的方法又会怎样呢
>>> class_a._get_a()
3
# 咦,竟然也能访问,思考片刻,,,,,,,,

猜想原因:class_a = A()将一个对象整体实例化,是不是类似直接import script整个module,所以才能访问类的看似像私有的属性和方法,但是双下划线为类的私有成员,如下

class A:
    def __init__(self):
        self.a = 1
        self.__b = 2
    def __get(self):
        return 6

instance_a = A()

>>> instance_a.__b
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'A' object has no attribute '__b'

>>> instance_a.__get()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'A' object has no attribute '__get'


底层用C编写的扩展库

另外单下划线开头还有一种一般不会用到的情况在于使用一个 C 编写的扩展库有时会用下划线开头命名,然后使用一个去掉下划线的 Python 模块进行包装。如 struct 这个模块实际上是 C 模块 _struct 的一个 Python 包装。

2. 后单下划线,如class_

  • 后单下划线是想用类似 class, else, dict命名,但是python规范中规定是不能用这些关键字命名变量的。好吧,但是这时候后单下划线起作用了,class_, else_, dict_这样的命名既能更加语义,又符合规范,yeah!散花!

二、 双下划线

1. 前双下划线,如 __suggest()

这种前双下划线一般用在Python的类中,为了区别父类和子类中函数的命名冲突,如

class A:
    def __a(self):
        pass
class B(A):
    def __a(self):
        pass
instance_b = B()
print(instance_b.__dir__())
# 结果如下
['__module__', '_B__a', '__doc__', '_A__a', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']

有上可知,_B__a, _A__a区别开了哪个类的方法,good!

2. 前后都有双下滑线,如__reduce__

前后都有双下滑线的有两种情况:
第一种,有一个通用的很魔法的名字,叫做魔法函数(Magic Method);
第二种是全局名,如__file__、__name__ 等, __name__指向模块的名字,__file__指向该模块的导入文件名

记笔记过程中的自我答疑:

  1. 类中一定要有init函数么
    答: it isn't necessary。只是一个常见的操作,因为实例化一个类通常通过init函数来存储或者初始化一个写状态信息(state informtion)以供类中的函数做一些需要的操作。

However, defining__init__ is a common practice because instances of a class usually store some sort of state informtion or data and the methods of the class offer a way to manipulate or do something with that state information or data. __init__allows us to initialize this state information or data while creating an instance of the class.
https://stackoverflow.com/questions/6854080/is-it-necessary-to-include-init-as-the-first-function-every-time-in-a-class

  1. 为什么叫magic method

待更新ing...

Reference:
Python 的类的下划线命名有什么不同?

你可能感兴趣的:(2018-01-24 python中的下划线使用解释)