变量、系统变量
- 1.变量
- 1.1 变量 定义/类型
- 1.2 变量 命名规范
- 1.3 变量 计算/类型转换
- 1.4 变量 可变/不可变类型
- 1.5 变量 作用域局部/全局
- 2.系统变量
- 3.xxxx
- 3.1 input()-从终端输入数据, 用变量存储
- 3.2 实参数
程序是用来处理数据
变量是用来存储数据的
函数是具有某一特定功能的代码块, 函数常来源对重复代码的抽象凝练。
好用变量操作方法
type() # 查看变量数据类型
id() # 查看变量内存地址
int() # 显式类型转换
float()
1.变量
1.1 变量 定义/类型
Python定义变量时不需要指定数据类型,解释器会依据等号右边的数据自动推导出变量中保存的类型。常见的数据类型:
数值型: – 整型(int)、浮点型(float)、布尔型(非零即是)、复数型(complex,用于数学计算)
非数值型: 序列 – 列表、字符串、元组、Unicode字符串、字节数组、缓冲区、Xrange对象
映射 – 字典
python2.0整数类型: int -整型、long-长整形
Python3.0整数类型: 整形、长整型统一定义为int
# 定义方式test
a = 1 # 定义方式1: 变量名=值 直接赋值,就是定义了一个变量。(变量使用前都要赋值)。
num1 = 2 # 定义方式2: 以通过数值计算表达式定义变量。
num2 = 3
num3 = num1 * num2
# 查看变量数据类型test type()--查看变量的数据类型
>>> a = 1 # type(a) => <class 'int'>
>>> a = "a" # type(a) => <class 'str'>
>>> b = [1] # type(b) => <class 'list'>
Pycharm 调试时能够从变量窗口查看变量类型
1.2 变量 命名规范
1.变量名要见名知义,由字母数字下划线组成,数字不能开头;
2.变量命由多个单词组成时,每个单词都使用小写字母,单词与单词之间用下划线连接。
python语言字母区分大小写, 其他常用命名方法(其他语言)
(小驼峰:第一个单词以小写字母开头,后面的单词以大写字母开头)
(大驼峰:所有单词均以大写字母开头)
注意事项
标标符:程序员定义的变量名、函数名。命名字要见名知义,由字母数字下划线组成,数字不能开头。
关键字:python内部已经使用的标识符,用户定义的标识符不能和关键字相同。命令可用于查Python关键字。(False、 True、…)
import keyword
print(keyword.kwlist)
1.3 变量 计算/类型转换
同/不同类型的变量计算
数值型:可以进行同类型的加、减、乘、除计算,py2.x 与py3.x存在不同的“隐式”类型转换。
字符串:重载了加号和乘号, 加号-字符串的拼接, 乘号-字符串翻倍
# 不同类型的变量计算test # 在py2.7 和py3.7分别进行了两次相同的输入试验
>>> 1.5 + 1 # both => 2.5
>>> 3 / 1.5 # both => 2.0
>>> 3 / 2 # py2.x => 1 py3.x浮点型 => 1.5
>>> "c" + "yy" # both => 'cyy'
>>> "c" * 5 # both => 'ccccc'
>>> "cc" - "c" # both => TypeError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'str' and 'str'
显式数据类型转换
int(x):将变量x转换成整形
float(x):将变量x转换成浮点型
# 显式数据类型转换test
>>> a = "12" # 以下操作a本身的数据类型不变,为<class 'str'>
>>> b = 12.5
>>> int(a) # => 12
>>> int(b) # => 12
>>> float(a) # => 12.0
>>> float(b) # => 12.5
1.4 变量 可变/不可变类型
python中的数据类型有可变/不可变之分:
- 不可变数据类型–数字,字符串,元组
- 可变数据类型–列表、字典
数据 保存在内存中的一个位置,但是内存地址是一个不便使用的数字,通过python解释器就能给这块内存地址取一个“别名”(变量名)
变量名只是内存地址的引用,其中保存着数据在内存中的地址,实际就是引用了某个数据,要访问数据时,通过解引用操作(自动)即可。
不可变数据类型 如何变? 不可变说的是无法通过简单的赋值操作来修改所指内存地址的数据。不可变数据类型的变量赋值操作时, python会自动申请另一块内存,该变量名指向新的内存地址。
优点:减少重复的值对内存空间的占用
缺点:每次修改变量的值,都需要重新开辟内存单元,给执行效率带来一定的影响。
# '变量不可变' test id(x)--查看x的指向的内存地址(查看数据的内存地址)
>>> a = 1 # id(a) => 140471515000552
>>> id(1) # => 140471515000552
>>> b = a # id(b) => 140471515000552 变量b和变量a都是引用了数据1的地址
>>> id(2) # => 140471515000528
>>> a = 2 # id(a) => 140471515000528 变量a指向的地址发生了变化,外在表现为值发生改变
>>> a = 1 # id(a) => 140471515000552 值再改回去变量名会指向原来的地址,作用机制非常神奇
>>> id(b) # => 140471515000552
# 小结: 一旦在某一个内存单元中指定了一个数字,这个单元中的数字就不能变了,但是a可以指向不同的地址,就好像a代表的数字在变一样。
# 看到赋值语句,把注意力放在等号的右边
列表、字典,可通过相关方法例如.append() .pop()等操作来修改内容,(地址不变), 【赋值操作同不可变类型变量一致,会修改变量的引用】
# List 可变性test
>>> a = [1, 2, 3] # id(a) => 140471604341568
>>> a.append(4) # id(a) => 140471604341568 不变
>>> a = [1, 2, 3, 4, 5] # id(a) => 140471604424944 变了
>>> a = [1, 2, 3, 4] # id(a) => 140471604341568 变回去
# dict 可变性test
>>> d = { "name": "xiaoming"} # id(d) => 140471604497008
>>> d["age"] = 18 # id(d) => 140471604497008
>>> d.pop("age") # id(d) => 140471604497008
>>> d
{'name': 'xiaoming'}
>>> d = {} # id(d) => 140471604533008 一赋值马上变
⚠️在python设置字典键值时,为了后续增删查改的方便,解释器会对key进行hash操作,以决定如何在内存中保存字典数据。所以key只能是可hash类型(不可变类型) --数字、元组、字符串;不能是可变类型–列表字典不行,否则会报错unhashable。
>>> d = {}
>>> d["name"] = "xiaoming" # 字符串作key 没问题
>>> d[1] = "zhengshu" # 数字 作key 没问题
>>> d[(1)] = "yuanzu" # 元组 作key 没问题
>>> d[[1,2,3]] # 列表 作key 报错unhashable
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
番外 哈希:看做一个函数,传入一个不可变数据类型,并且返回一个结果,提取数据的特征码,如果传递的内容是相同的,就能够返回相同的结果,如果传递的内容是不同的能够返回不同的结果。Hash函数只能接受一个不可变数据类型作为参数,不能接受可变类型参数。
# hash()操作test # hash输出
>>> hash(1) # => 1
>>> hash("hello") # => 840651671246116861
>>> hash("hello") # => 840651671246116861 相同的输入,输出相同
>>> hash((1,1)) # => 3713081631935493181
>>> hash([1, 2]) # 不可hash
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
【hash() 不同的输入可能会产生相同的输出,这种情况称为碰撞 ,这种概率极低】
1.5 变量 作用域局部/全局
局部变量:函数内部定义的变量,只能在定义它的函数中使用,用于[临时]保存一个函数内部使用的数据。
[生命周期]:创建到消亡,生命周期内才能使用变量。
[使用细节]:不同的函数内部,定义了相同名字变量,相互之间使用互不干扰。
全局变量:函数外定义的变量,能够在所有函数中都使用
[使用细节]:在函数内部,可以通过变量的引用获取对应的数据,但是不允许直接修改全局变量的引用。也就是只能用,不能对其使用赋值操作。
[定义位置]:在开发时,把所有的全局变量定义所有函数的上方,就可以保证所有的函数都能正常访访问所有的全局变量。
[命名规范]:不同公司对于全局变量的标记有不同的规则;在变量名前面增加gl_或者g_(到新的公司工作,可以问一下领导全局变量的命名规则)
# 函数内部尝试[直接]修改全局变量的值test.....fail
num=10
def demo_one():
# 尝试修改全局变量的值, 在python函数中不允许修改全局变量的值
# 使用赋值语句,会在函数内部定义一个局部变量
num = 99
print("demo_one=>%d" %num)
def demo_two():
print("demo_two=>%d" % num)
demo_one()
demo_two()
输出
demo_one=>99
demo_two=>10
global声明全局变量,可实现在函数内部修改全局变量的值:
# 函数内部[声明]修改全局变量的值test.....success
num=10
def demo_one():
# 希望修改全局变量的值,global声明一下,告诉解释器global后面变量是全局变量,就不会创建一个局部变量,而是直接修改全局变量num
global num
num = 99
print("demo_one=>%d" %num)
def demo_two():
print("demo_two=>%d" % num)
demo_one()
demo_two()
输出
demo_one=>99
demo_two=>99
⚠️在其他编程语言中,不推荐使用全局变量:可变范围大,导致函数不好维护。
⚠️在Python中有特定的设置,来避免一些问题。函数中要使用变量的时候,就近查找原则,找到就用。
2.系统变量
当 Python 解释器读取一个 Python 文件时,首先设置一些特殊变量,然后执行文件中的代码。
这些特殊变量包括:
# 系统变量
print("__doc__ is", __doc__) # 此文件最前方的三引号注释内容,若想此字段有效,三引号前不能存在非注释代码
print("__file__ is", __file__) # 当前文件存放的路径和文件名, 在当前目录/非当前目录下运行结果不一致,配合os.path.basename(), dirname()食用效果更佳
print("__name__ is ", __name__) # 当.py作为脚本直接执行时__name__=="__main__"; 当.py作为模块被import时__name__==文件名
输出
('__doc__ is', '\n@brief : test xxx\n')
('__file__ is', 'test.py')
('__name__ is ', '__main__')
3.xxxx
3.1 input()-从终端输入数据, 用变量存储
python2.x input() 自动识别输入数据的类型,raw_input()默认将输入流转化为字符串。
python3.x 只剩下input()函数可用,且输入数据的类型识别类型是字符串。
# python2.7 test
>>> a = input("请输入数字:")
请输入数字:3
>>> a
3
>>> a = raw_input("请输入数字:")
请输入数字:3
>>> a
'3'
# python3.7 test
>>> a = input("请输入数字:")
请输入数字:3
>>> a
'3'
>>> a = raw_input("请输入数字:")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'raw_input' is not defined
3.2 实参数
python 函数实参通过引用调用,调用函数时,传递的是 实参保存数据的地址(引用) ,创建形参局部变量。todo.
python 函数返回值传递引用(地址)