python 函数、变量中单下划线和双下划线的区别详解
作者:岳来 发布时间:2021-06-29 11:32:33
一、_func 单下划线开头 --口头私有变量
1.1、在模块中使用单下划线开头
在Python中,通过单下划线_来实现模块级别的私有化,变量除外。一般约定以单下划线开头的函数为模块私有的,也就是说from moduleName import * 将不会引入以单下划线开头的函数。模块中使用单下划线开头定义函数、全局变量和类均适用,但可以用:from module import _func形式单独导入。
实例如下:
lerarn_under_line.py
# coding=utf-8
course = "math"
_credit = 4
def call_var():
print "course:%s" % course
print "_credit:%d" % _credit
def _call_var():
print "带下划线course:%s" % course
print "带下划线_credit:%d" % _credit
def __call_var():
print "带双下划线course:%s" % course
print "带双下划线_credit:%d" % _credit
import lerarn_under_line
>>> import lerarn_under_line
>>> lerarn_under_line.call_var
<function call_var at 0x10aa61850>
>>> lerarn_under_line.call_var()
course:math
_credit:4
>>> lerarn_under_line._call_var() # 单下划线可以调用
带下划线course:math
带下划线_credit:4
>>> >>> lerarn_under_line.__call_var() # 双下划线不可调用
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__call_var'
from lerarn_under_line import *
>>> from lerarn_under_line import *
>>> course
'math'
>>> _credit
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_credit' is not defined
>>> call_var()
course:math
_credit:4
>>> _call_var()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_call_var' is not defined
>>> __call_var()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '__call_var' is not defined
from module import _func
>>> from lerarn_under_line import course
>>> course
'math'
>>> from lerarn_under_line import _credit
>>> _credit
4
>>> from lerarn_under_line import call_var
>>> call_var()
course:math
_credit:4
>>> from lerarn_under_line import _call_var
>>> _call_var()
带下划线course:math
带下划线_credit:4
>>> from lerarn_under_line import __call_var
>>> __call_var()
带双下划线course:math
带双下划线_credit:4
1.2、在类中使用单下划线开头
lerarn_under_line.py
class Course(object):
def __init__(self, name):
self.name = name
def credit(self):
if self.name == 'math':
print "%s的credit 为%d" % (self.name, 4)
else:
print "%s的credit 为%d" % (self.name, 2)
def _credit(self):
if self.name == 'math':
print "%s的credit 为%d" % (self.name, 4)
else:
print "%s的credit 为%d" % (self.name, 2)
def __credit(self):
if self.name == 'math':
print "%s的credit 为%d" % (self.name, 4)
else:
print "%s的credit 为%d" % (self.name, 2)
import lerarn_under_line
>>> import lerarn_under_line
>>> a=Course('math')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Course' is not defined
from lerarn_under_line import *
>>> from lerarn_under_line import *
>>> a=Course('math')
>>> a.credit()
math的credit 为4
>>> a._credit()
math的credit 为4
>>> a.__credit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Course' object has no attribute '__credit'
from lerarn_under_line import Course
>>> from lerarn_under_line import Course
>>> a=Course('math')
>>> a.__credit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Course' object has no attribute '__credit'
>>> a._credit()
math的credit 为4
>>> a.credit()
math的credit 为4
综上,单下划线开头的函数表示是口头实例私有变量,是可访问的,但是也不要随意访问,即所谓防君子不防小人。
二、__func 双下划线开头的函数 --私有变量
2.1、在模块中使用双下划线开头
在实例中,带双下划线的类变量、实例变量、方法不能被直接访问。但有办法间接访问。如1.1中的from module import __func
>>> from lerarn_under_line import *
>>> __call_var()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '__call_var' is not defined
>>> import lerarn_under_line
>>> lerarn_under_line.__call_var() # 双下划线不可调用
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__call_var'
>>> from lerarn_under_line import course
>>> from lerarn_under_line import __call_var
>>> __call_var()
带双下划线course:math
带双下划线_credit:4
2.2、在类中使用双下划线开头
在class类的内部,带双下划线的类变量、实例变量、方法具有正常访问权限。
在继承结构中,带双下划线的基类的类变量和实例变量不能被子类直接访问。
lerarn_under_line.py
class Course(object):
def __init__(self, name, _teacher, __classroom):
self.name = name
self._teacher = _teacher
self.__classroom = __classroom
def call_var(self):
print "name:%s" % self.name
print "_teacher:%s" % self._teacher
print "__classroom:%s" % self.__classroom
>>> import lerarn_under_line
>>> a = Course('math', 'zhangyu', 'juyiting') # 无法实例化
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Course' is not defined
>>> from lerarn_under_line import *
>>> a = Course('math', 'zhangyu', 'juyiting')
>>> a.call_var()
name:math
_teacher:zhangyu
__classroom:juyiting
lerarn_under_line.py
class Course(object):
def __init__(self, name, _teacher, __classroom):
self.name = name
self._teacher = _teacher
self.__classroom = __classroom
def call_var(self):
print "name:%s" % self.name
print "_teacher:%s" % self._teacher
print "__classroom:%s" % self.__classroom
class SonCourse(Course):
def __init__(self, name, _teacher, __classroom, time):
super(Course, self).__init__()
self.time = time
self.name = name
self.__classroom = self.__classroom
self._teacher = self._teacher
self.__classroom = self.__classroom
def call_son_var(self):
print "time:%s" % self.time
print "name:%s" % self.name
print "_teacher:%s" % self._teacher
print "__classroom:%s" % self.__classroom
>>> import lerarn_under_line
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lerarn_under_line.py", line 77, in <module>
b = SonCourse('math', 'zhangyu', 'juyiting', "12:00")
File "lerarn_under_line.py", line 63, in __init__
self.__classroom = self.__classroom
AttributeError: 'SonCourse' object has no attribute '_SonCourse__classroom'
>>> from lerarn_under_line import *
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lerarn_under_line.py", line 77, in <module>
b = SonCourse('math', 'zhangyu', 'juyiting', "12:00")
File "lerarn_under_line.py", line 63, in __init__
self.__classroom = self.__classroom
AttributeError: 'SonCourse' object has no attribute '_SonCourse__classroom'
>>> from lerarn_under_line import Course
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lerarn_under_line.py", line 77, in <module>
b = SonCourse('math', 'zhangyu', 'juyiting', "12:00")
File "lerarn_under_line.py", line 63, in __init__
self.__classroom = self.__classroom
AttributeError: 'SonCourse' object has no attribute '_SonCourse__classroom'
>>> from lerarn_under_line import sonCourse
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lerarn_under_line.py", line 77, in <module>
b = SonCourse('math', 'zhangyu', 'juyiting', "12:00")
File "lerarn_under_line.py", line 63, in __init__
self.__classroom = self.__classroom
AttributeError: 'SonCourse' object has no attribute '_SonCourse__classroom'
三、前后都有双下划线 --特殊变量
Python保留了有双前导和双末尾下划线的名称,用于特殊用途。 这样的例子有,init__对象构造函数,或__call — 它使得一个对象可以被调用。这些方法通常被称为神奇方法,最好避免在自己的程序中使用以双下划线开头和结尾的名称,以避免与将来Python语言的变化产生冲突。
常见方法:
方法 | 含义 |
---|---|
__str__ | 当将对象转换成字符串时会执行 |
__init__ | 初始化方法,为对象变量赋值 |
__new__ | 构造方法,创建一个对象 |
__call__ | 在对象后面加括号会执行该方法 |
__getattr__ | 当使用对象.属性时,若属性不存在会调用该方法 |
__setattr__ | 当使用对象.属性 = 值,会调用该方法 |
__iter__ | 类内部定义了该方法,对象就变成了可迭代对象 |
__add__ | 当两个对象使用+号会调用该方法 |
__enter__和__exit__ | 上下文管理 |
参考文档
1、https://blog.csdn.net/brucewong0516/article/details/79120841
2、http://t.zoukankan.com/one-tom-p-11749739.html
3、https://www.cnblogs.com/bryant24/p/11429653.html
4、https://blog.csdn.net/m0_58357932/article/details/121062461
5、https://www.likecs.com/show-308380836.html
来源:https://blog.csdn.net/yuelai_217/article/details/128706898
猜你喜欢
- 更多的信息,可以参考python内部的json文档: python>>> help(json) 或者官方文档: http:
- 数字序号① ①② ②③ &
- python 使用get_argument获取url query参数ornado的每个请求处理程序,我们叫做handler,handler里
- mysql win10 解压缩下载 解压Mysql :版本 5.7.13 下载链接 (通过这个官网zip链接可以直接下载,不用再注册 Ora
- 1.2 本篇文章内容概要1.3 本篇文章内容概括在SQL语句中,关于表连接,若按照表的数量来划分,可以划分为单表连接、两表连接和两表以上连接
- 有一些问题可能会遇到同元素多列去重问题,下面介绍一种非常简单效率也很快的做法,用pandas来实现。首先我们看一下数据类型:G1 G2a b
- 为了配置基于 mod_python 的 Django,首先要安装有可用的 mod_python 模块的 Apache。 这通常意味着应该有一
- 一、图的定义图是一种比树更复杂的一种数据结构,在图结构中,结点之间的关系是任意的,任意两个元素之间都可能相关,因此,它的应用极广。图中的数据
- 今天学习了用python生成仿真数据的一些基本方法和技巧,写成博客和大家分享一下。 本篇博客主
- 执行环境会负责管理代码执行过程中使用的内存,编写JavaScript程序时,所需内存的分配以及无用内存的回收完全实现自动管理。原理:找出那些
- Dreamweaver MX 2004 试用试用心得:安装:选择工作界面(我选了默认的设计模式)初次启动,选择30天试用如果你也看到这个警告
- 和其他数据库系统类似,Oracle字符串连接使用“||”进行字符串拼接,其使用方式和MSSQLServer中的加号“+”一样。 比如执行下面
- 本文实例分析了python开发之str.format()用法。分享给大家供大家参考,具体如下:格式化一个字符串的输出结果,我们在很多地方都可
- 目前lnmp一键安装包比较多的问题就是502 Bad Gateway,大部分情况下原因是在安装php前,脚本中某些lib包可能没有安装上,造
- MySQL行转列操作 所谓的行转列操作,就是将一个表的行信息转化为列信息,说着可能比较笼统,这里先举个例
- Python 模块概念python中的模块是什么?简而言之,在python中,一个文件(以“.py”为后缀名的文件)就叫做一个模块,每一个模
- 代码如下:--执行顺序 From Where Select select * from (select sal as salary,comm
- 其实我这样做的本意是为了防止盗链!大家帮忙看一下通过代码能够根治盗链!只要不是HTTP_REFERER来源于(google.com goog
- 废话不多说了直接给大家介绍canvas实现手机端用来上传用户头像的代码,具体代码如下所示:<!DOCTYPE html><
- 本文实例讲述了javascript面向对象三大特征之封装。分享给大家供大家参考,具体如下:封装封装(Encapsulation):就是把对象