1.3.1 Python 变量
1. 变量的基本概念
在 Python 里,变量是存储数据的容器,其存在意义重大。它能让开发者在程序里保存数据,还能随时调用和修改这些数据。从本质上来说,变量是计算机内存地址的抽象表示。下面从计算机原理角度出发,深入剖析 Python 变量的底层实现逻辑。
在 Python 中创建变量时,比如x = 10,实际上是在内存里开辟了一块空间来存放整数10,同时让变量名x指向这个内存地址。Python 是动态类型语言,这意味着无需提前声明变量类型,解释器会依据赋值自动确定类型。
2. 计算机底层实现逻辑
内存管理
Python 采用对象模型,所有数据都是对象。当你创建变量时,Python 解释器会:
- 先在内存中创建一个对象(像整数、字符串等);
- 接着给这个对象分配内存地址;
- 最后把变量名和这个内存地址关联起来。
以x = 10为例,Python 会创建一个int对象,其值为10,然后让x指向该对象的内存地址。
引用计数
Python 使用引用计数来管理内存。每个对象都有一个引用计数器,当有新的引用指向该对象时,计数器加 1;当引用被删除时,计数器减 1。当计数器变为 0 时,对象占用的内存就会被释放。
x = 10 # 创建对象 10,x 引用它,引用计数为 1
y = x # y 也引用 10,引用计数变为 2
del x # 删除 x 引用,引用计数减为 1
print(y) # 10,对象 10 仍存在,因为 y 还在引用它
del y # 删除 y 引用,引用计数变为 0,对象 10 被销毁
3 变量创建与命名规则
在 Python 程序里,变量通过变量名来表示,其数据类型可以是任意的。和其他编程语言(例如 Shell)相同,= 作为赋值语句。
count = 100 # 整型变量
message = 'hello' # 字符串变量
需要注意的是,变量名应当满足以下要求:
-
变量名的开头必须是字母或者下划线字符。
-
变量名不能以数字开头。
-
变量名只能由字母数字字符以及下划线(A - z、0 - 9 和 _)组成。
-
变量名区分大小写,像 age、Age 和 AGE 就是三个不同的变量。
-
变量名不能使用 Python 的保留字。
-
避免使用 Python 的内置函数名(如
int、str)作为变量名,否则会覆盖内置函数的功能。
4. 多变量赋值
# 一行中为多个变量赋值
x, y, z = "Orange", "Banana", "Cherry"
print(x) # 输出: Orange
print(y) # 输出: Banana
print(z) # 输出: Cherry
# 为多个变量分配相同的值
x = y = z = "Orange"
print(x) # 输出: Orange
print(y) # 输出: Orange
print(z) # 输出: Orange
5. 输出变量
# 结合文本和变量
x = "awesome"
print("Python is " + x) # 输出: Python is awesome
# 变量相加
x = "Python is "
y = "awesome"
z = x + y
print(z) # 输出: Python is awesome
# 数字运算
x = 5
y = 10
print(x + y) # 输出: 15
6. 全局变量
- 在函数外部创建的变量称为全局变量
- 全局变量可以被函数内部和外部的代码使用
- 使用
global关键字可以在函数内部创建或修改全局变量
# 全局变量示例
x = "awesome"
def myfunc():
global x
x = "fantastic"
print("Python is " + x)
myfunc() # 输出: Python is fantastic
print("Python is " + x) # 输出: Python is fantastic
7. name 与 main
在 Python 中,__name__ 和 __main__ 是两个特殊的变量,用于控制代码的执行方式。这对于编写既可以作为脚本运行,也可以作为模块导入的代码非常有用。
__name__ 变量
__name__ 是一个内置变量,用于表示当前模块的名称:
- 当模块作为主程序运行时,
__name__的值被设置为"__main__" - 当模块被导入时,
__name__的值被设置为模块的文件名(不包括 .py 扩展名)
示例:
# module.py
print(f"模块的 __name__ 值: {__name__}")
# 直接运行 module.py 时输出:
# 模块的 __name__ 值: __main__
# 在其他文件中导入 module.py 时输出:
# 模块的 __name__ 值: module
__main__ 的含义
__main__ 是一个特殊的字符串,用于表示当前模块是作为主程序运行的。它通常与 __name__ 变量一起使用,以确定模块是被导入还是作为独立脚本运行。
使用 if name == "main": 的常见模式
在 Python 中,常见的做法是在模块的末尾添加以下代码块:
if __name__ == "__main__":
# 这里的代码只有在模块作为主程序运行时才会执行
main()
这种模式允许模块在被导入时不会执行某些代码,而只有在作为独立脚本运行时才会执行这些代码。
1.3.2 Python 基本数据类型
1. 字符串
字符串英文 string,是 python 中随处可见的数据类型,字符串的识别也非常的简单,就是用 引号括起来的。
引号包括单引号' ', 双引号" " 和三引号''' ''',比如'abc', "123"等等。
注意上述案例中,字符串的内容只有abc和123,引号并非字符串的内容,那么就产生了疑问,如何标识引号本身这个字符串呢,可以采用引号交替使用,即'"'用来标识字符串双引号。或者可以用转义符\对引号进行转义。
print('hello, 我是双引号"!')
# 将输出hello,我是双引号"
print("hello, 我是双引号\"")
# 将输出hello,我是双引号"
2. 整数
整数英文为 integer。代码中的整数跟我们平常认识的整数一样,包括正整数、负整数和零,即没有小数点的数字。如:1 、100 、-100 、0等等。当然,要注意,如果数字用引号括起来了,那就属于字符串,而不属于整数,比如'100'。
整数可以进行算数运算。
int1 = 100
int2 = '100'
print(int1)
print(type(int1))
print(int2)
print(type(int2))
'''
将输出如下信息:
100
<class 'int'>
100
<class 'str'>
'''
type 是 python 内置函数,可以用于查看变量的数据类型。
3. 浮点数
浮点数的英文名是 float ,是指带小数的数字。
浮点数同整数一样,可以进行算数运算。
4. 数据类型转换注意事项
-
转换规则:
- 整数可以转换为浮点数
- 浮点数转换为整数会截断小数部分
- 字符串转换为数字时,字符串必须只包含数字
- 任何类型都可以转换为字符串
-
常见错误:
- 将非数字字符串转换为数字会引发
ValueError - 将不兼容的类型进行转换会引发
TypeError
- 将非数字字符串转换为数字会引发
-
最佳实践:
- 在进行类型转换前,最好先检查数据是否可以进行转换
- 使用try-except处理可能的转换错误
- 明确指定转换类型,避免依赖隐式转换
示例:安全的类型转换
def safe_convert(value, target_type):
try:
return target_type(value)
except (ValueError, TypeError):
return None
# 使用示例
result = safe_convert("123", int) # 返回 123
result = safe_convert("abc", int) # 返回 None
4. 类型转换的应用场景
- 用户输入处理(将字符串转换为数字)
- 数据格式化(将数字转换为字符串)
- 数据库操作(类型转换以适应数据库要求)
- API接口(处理不同数据类型的转换)
1.3.3 Python 运算符
1. 算术运算符
算术运算符用于执行基本的数学运算:
| 运算符 | 描述 | 实例 |
|---|---|---|
| + | 加 | a + b |
| - | 减 | a - b |
| * | 乘 | a * b |
| / | 除 | a / b |
| % | 取模 | a % b |
| ** | 幂 | a ** b |
| // | 取整除 | a // b |
示例:
a = 10
b = 3
print(a + b) # 输出: 13
print(a - b) # 输出: 7
print(a * b) # 输出: 30
print(a / b) # 输出: 3.3333333333333335
print(a % b) # 输出: 1
print(a ** b) # 输出: 1000
print(a // b) # 输出: 3
2. 比较运算符
比较运算符用于比较两个值:
| 运算符 | 描述 | 实例 |
|---|---|---|
| == | 等于 | a == b |
| != | 不等于 | a != b |
| > | 大于 | a > b |
| < | 小于 | a < b |
| >= | 大于等于 | a >= b |
| <= | 小于等于 | a <= b |
示例:
a = 10
b = 3
print(a == b) # 输出: False
print(a != b) # 输出: True
print(a > b) # 输出: True
print(a < b) # 输出: False
print(a >= b) # 输出: True
print(a <= b) # 输出: False
3. 赋值运算符
赋值运算符用于给变量赋值:
| 运算符 | 描述 | 实例 |
|---|---|---|
| = | 简单赋值 | c = a + b |
| += | 加法赋值 | c += a 等价于 c = c + a |
| -= | 减法赋值 | c -= a 等价于 c = c - a |
| *= | 乘法赋值 | c *= a 等价于 c = c * a |
| /= | 除法赋值 | c /= a 等价于 c = c / a |
| %= | 取模赋值 | c %= a 等价于 c = c % a |
| **= | 幂赋值 | c **= a 等价于 c = c ** a |
| //= | 取整除赋值 | c //= a 等价于 c = c // a |
示例:
a = 10
b = 3
c = a + b
print(c) # 输出: 13
c += a
print(c) # 输出: 23
c -= b
print(c) # 输出: 20
c *= 2
print(c) # 输出: 40
4. 逻辑运算符
逻辑运算符用于组合条件:
| 运算符 | 描述 | 实例 |
|---|---|---|
| and | 逻辑与 | x and y |
| or | 逻辑或 | x or y |
| not | 逻辑非 | not x |
示例:
x = True
y = False
print(x and y) # 输出: False
print(x or y) # 输出: True
print(not x) # 输出: False
5. 位运算符
位运算符用于对二进制数进行操作:
| 运算符 | 描述 | 实例 |
|---|---|---|
| & | 按位与 | a & b |
| | | 按位或 | a | b |
| ^ | 按位异或 | a ^ b |
| ~ | 按位取反 | ~a |
| << | 左移 | a << b |
| >> | 右移 | a >> b |
示例:
a = 60 # 二进制: 0011 1100
b = 13 # 二进制: 0000 1101
print(a & b) # 输出: 12 (二进制: 0000 1100)
print(a | b) # 输出: 61 (二进制: 0011 1101)
print(a ^ b) # 输出: 49 (二进制: 0011 0001)
print(~a) # 输出: -61 (二进制: 1100 0011)
print(a << 2) # 输出: 240 (二进制: 1111 0000)
print(a >> 2) # 输出: 15 (二进制: 0000 1111)
6. 成员运算符
成员运算符用于测试序列中是否包含某个值:
| 运算符 | 描述 | 实例 |
|---|---|---|
| in | 如果在指定的序列中找到值返回True | x in y |
| not in | 如果在指定的序列中没有找到值返回True | x not in y |
示例:
list1 = [1, 2, 3, 4, 5]
print(3 in list1) # 输出: True
print(6 not in list1) # 输出: True
7. 身份运算符
身份运算符用于比较两个对象的存储单元:
| 运算符 | 描述 | 实例 |
|---|---|---|
| is | 判断两个标识符是否引用同一个对象 | x is y |
| is not | 判断两个标识符是否引用不同对象 | x is not y |
示例:
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a is b) # 输出: False
print(a is c) # 输出: True
print(a is not b) # 输出: True
8. 运算符优先级
Python运算符的优先级从高到低如下:
- 括号:
() - 幂运算:
** - 一元运算符:
+x,-x,~x - 乘除取模取整除:
*,/,%,// - 加减:
+,- - 位移:
<<,>> - 按位与:
& - 按位异或:
^ - 按位或:
| - 比较运算符:
==,!=,>,<,>=,<= - 身份运算符:
is,is not - 成员运算符:
in,not in - 逻辑运算符:
not,and,or
示例:
a = 2 + 3 * 4
print(a) # 输出: 14 (先计算3*4,再加2)
b = (2 + 3) * 4
print(b) # 输出: 20 (先计算2+3,再乘4)
9. 运算符使用注意事项
-
类型兼容性:
- 确保运算符两边的操作数类型兼容
- 注意隐式类型转换可能带来的问题
-
优先级和结合性:
- 使用括号明确运算优先级
- 注意运算符的结合性(左结合或右结合)
-
短路求值:
- 逻辑运算符
and和or具有短路特性 - 第一个操作数就能确定结果时,不会计算第二个操作数
- 逻辑运算符
-
浮点数比较:
- 浮点数比较时要注意精度问题
- 建议使用
math.isclose()进行浮点数比较
-
性能考虑:
- 位运算通常比算术运算更快
- 成员运算符
in对列表和元组是O(n)复杂度 - 对集合和字典是O(1)复杂度
评论区