python类中的下划线"_"的含义综合

若如初见. 提交于 2020-02-14 08:19:16

Python中下划线的使用是多种多样的,不是简单的Python中的雷属性加了下划线是私有变量,python中并不存在这个概念。

  1. 函数返回值等无用变量,例如
# 函数的两个返回值这里就忽略了
a, b, _, _ = function(x,y)
# enumerate
for ind, vol in enumerate(vol_list): #正常的使用
for _, vol in enumerate(vol_list): #忽略变量的使用
  1. 模块内的变量、函数、类名

    如果在模块中定义了下划线开头的变量、函数或者类的话,__from module import *__不会将这些变量import到文件内(一种类似隐藏的功能)。但是想使用模块中的_name也可以,有三种方式:
    ① 在py文件引用部分import module,需要使用其中的下划线部分可以通过module._name来调用

    ② 使用from module import _name

    ③ 如果在模块的"_all_"属性中已经包含了_name的话,from module import *也是可以直接导入的。

  2. 类内下划线开头的属性和函数
    其中下划线包括单下划线双下划线,两者并不相同。

    ① 对于单下划线来说:
    如果没有**@property**装饰器修饰的话,和普通的变量是没有区别的,可以随意使用成员运算符“.”来对属性进行引用或者赋值。也就是说,如果用了下划线修饰的话,就要用@property,并重写setter。这里还要说明的一点是==@property修饰器就是getter,setter还是setter,当然你可以再写一个getter,会覆盖property的函数,但是property修饰器不能不写==,所以一般只写@property和@setter。同时单下划线允许类内访问和实例访问,派生类不可以访问。
    一个例子如下:

class Professor():
	_university = 'Oxford'
	def __init__(self, ind):
		self._ind = ind

L = Professor(615)
print(L._university)
print(L._ind)

输出结果是:

615
Oxford

但是我们像下面一样使用了property修饰符的话,如下所示:

class Professor():
	_university = 'Oxford'
	def __init__(self, ind):
		self._ind = ind
	
	@property
	def ind(self):
		print('get_ind')
		return self._ind
	
	@id.setter
	def ind(self, new_ind):
		print('set_ind')
		self._ind = new_ind

L = Professor(615)
print(L._ind)

L.ind = 100
print(L.ind)

L._ind = 200
print(L._ind)

相应的输出结果是:

615   #来自 print(L._ind)
set_ind # 来自L.ind = 100
get_ind # 来自print(L.ind)
100 # 来自print(L.ind)
200 # 来自print(L._ind),注意没有get_ind

从结果中观察发现,如果使用@property修饰的话,我们在用实例对属性进行调用的时候L.ind,会调用相应的property(getter)函数和setter函数,但是你还是可以通过L._ind绕过property来访问。

再一个例子:

class Professor():
    _university = 'Oxford'

    def __init__(self, ind):
        self._ind = ind

    @property
    def ind(self):
        print('get_ind')
        return self._ind

    @ind.setter
    def ind(self, new_ind):
        print('set_ind')
        self._ind = new_ind

    @ind.getter
    def ind(self):
        print('getter_ind')
        return self._ind

L = Professor(615)
print(L._ind)

L.ind = 100
print(L.ind)

L._ind = 200
print(L._ind)

输出的结果是:

615
set_ind
getter_ind
100
200

② 对于双下划线,类似于protect变量,仅允许类内部访问,类实例和派生类均不能访问此属性和方法。例子如下:

class Professor():
    _university = 'Oxford'

    def __init__(self, ind):
        self.__ind = ind

    @property
    def ind(self):
        print('get_ind')
        return self.__ind

    @ind.setter
    def ind(self, new_ind):
        print('set_ind')
        self.__ind = new_ind

L = Professor(615)
print(L.ind)

L.ind = 100
print(L.ind)

#L.ind = 200
#print(L.__ind)  #报错 AttributeError: 'Professor' object has no attribute '__ind'

输出的结果如下:

get_ind # 来自print(L.ind)
615 # 来自print(L.ind)
set_ind # 来自L.ind = 100
get_ind # 来自print(L.ind)
100 # 来自print(L.ind)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!