你好,我是 hockor,今天继续我们的 Python 系列第二节,本节内容咱们主要讲一讲 Python 的基础语法、作用域、变量和基础数据类型。话不多说,我们开始吧~
缩进
Python使用缩进来定义代码块,这是它区别于JavaScript最明显的语法特征之一。缩进通常是4个空格或1个制表符,比如下面这个 Python 函数(def 关键字是 Python 中定义函数的语法,类似于 js 中的 function)
python
# 正确的缩进
def calculate_sum(a, b):
result = a + b
if result > 0:
print("正数")
else:
print("负数或零")
return result
# 错误的缩进会导致IndentationError
def wrong_function():
result = 1 # 这行缺少缩进
return result # 这行缩进不一致
缩进的重要规则:
- 同一代码块中的语句必须有相同的缩进级别
- 每进入一个新的代码块(如函数定义、循环、条件语句等),缩进增加一级
- 离开代码块时,缩进减少到之前的级别
- Python建议使用4个空格作为标准缩进
在 JavaScript 中我们一般使用大括号来定义代码块,而在 Python 中,除了集合和字典里面会用到大括号,代码块根本看不到任何大括号的影子
Python的这种强制缩进规则有助于保持代码的一致性和可读性,但对初学者来说可能需要一段时间来适应。
作用域
上面讲到了 Python 使用缩进来定义代码块,那么显然类比 JS,Python 的作用域从内到外依次是:
- **Local(局部作用域):**函数内部的变量
- **Enclosing(闭包作用域):**嵌套函数中外层函数的变量
- **Global(全局作用域):**模块级别的变量
我们来看一个局部作用域和全局作用域的例子
python
y = 20 # 全局变量
def modify_var():
y = 30 # 局部变量(与全局变量同名)
print("Inside function:", y) # 30
modify_var()
print("Outside function:", y) # 全局变量未被修改,依旧打印 20
global 关键字
如果我们想要修改全局作用域的 y,Python 给我们提供了一个global
关键字,代码示例如下
python
y = 20 # 全局变量
def modify_var():
global y # 声明要修改的是全局变量 y
y = 30 # 现在修改的是全局变量,而非创建局部变量
print("Inside function:", y)
modify_var()
print("Outside function:", y) # 全局变量已被修改
nonlocal关键字
还有一种场景,比如我在一个函数中想要修改外部函数的变量,但是它不是一个全局变量,这时候就要用到 nonlocal 这个关键字,比如下面这个闭包的场景
python
def outer():
y = 10 # 外层函数的局部变量
def inner():
nonlocal y # 声明要修改的是外层函数的 y
y = 20 # 修改外层函数的 y
inner()
print(y) # 输出 20(外层变量被修改)
outer()
再来看一个更复杂的例子
python
z = 100 # 全局变量
def outer():
z = 10 # 外层函数的局部变量
def inner():
nonlocal z # 修改 outer 的 z
z = 20
inner()
print("outer z:", z) # 输出 20
def inner_global():
global z # 修改全局的 z
z = 999
inner_global()
print("outer z after inner_global:", z) # 仍然是 20(不影响 outer 的 z)
outer()
print("global z:", z) # 输出 999(全局变量被修改)
变量
在 JavaScript 中,其中抛开 var 不说,我们一般用 let 来定义一个变量,const定义一个常量,而在 Python 中,我们压根不需要声明关键字。语法很简单
变量名=变量值,比如:
python
# Python
name = "John"
age = 25
score = 100
那么 Python 中如何定义常量呢,答案是:没法定义。
在 Python 中人们一般约定俗成使用全大写来标志一个变量是常量,但是也仅仅只是命名上的约束而已,而没有解释器层面的报错
python
# Python中的"常量"(实际上仍然可以修改)
MAX_VALUE = 100
PI = 3.14159
# 可以修改,但按照约定不应该这样做
MAX_VALUE = 200 # 这是允许的,但不推荐
相比之下,JavaScript中的const声明的变量不能被重新赋值:
jsx
// JavaScript
const MAX_VALUE = 100;
MAX_VALUE = 200; // 错误:不能重新赋值const变量
let score = 90; // let声明的变量可以重新赋值
score = 95; // 这是允许的
这是两种语言在变量声明和常量处理方面的一个重要区别。Python通过编码规范而不是语法限制来处理常量。
基础数据类型
Python 中的数据类型大致包含有整数(int) 、浮点数(float) 、布尔值(bool) 、字符串(str) 、元组(tuple) 、列表(list) 、字典(dict)和集合(set)。
整体上对于前端开发者还是比较好理解的,我们今天先来看看整数、浮点数、布尔值和字符串。
数字类型
Python区分整数(int)和浮点数(float),而JavaScript只有一种数字类型(Number)。
jsx
// JavaScript
let num1 = 42; // Number
let num2 = 42.0; // 同样是Number
typeof num1; // 'number'
typeof num2; // 'number'
而 Python 中
python
# Python
num1 = 42 # int
num2 = 42.0 # float
type(num1) # <class 'int'>
type(num2) # <class 'float'>
我们可以使用 isInstance 方法来判断
python
age = 20
score = 95.5
# 如何判断是一个整数
print('age is int:', isinstance(age, int)) # True
print('score is int:', isinstance(score, int)) # False
# 如何判断是一个浮点数
print('age is float:', isinstance(age, float)) # False
print('score is float:', isinstance(score, float)) # True
然后有一个有趣的点,在Python中,bool 是 int 的子类,这是一个有趣的特性,比如下面的 demo
python
# Python中的bool是int的子类
isinstance(True, int) # 返回True
isinstance(False, int) # 返回True
# True和False可以参与数值运算
True + True # 结果为2
False + 1 # 结果为1
# 但是不能给bool类型赋予其他数值
True = 2 # 这会导致SyntaxError
这种设计是为了保持向后兼容性,因为在早期的Python版本中,布尔值是用0和1表示的。这种继承关系使得布尔值可以在需要时自动转换为整数,但是它不是咱们 JS 中的隐式转换,这一点大家要清楚。
布尔值
在 Python 中,True 和 False 都是关键字,表示布尔值,唯一需要注意的就是上面提到的 bool 是 int 的子类,因此布尔值可以被看作整数来使用,其中 True 等价于 1,False 等价于 0。
字符串
这里我们主要讲一下 Python 中的字符串格式化的演进过程,这点和 JS 有点不一样。
% 占位符
这个就是类似于 C 语言的 printf 风格,支持 %s(字符串)、%d(整数)、%f(浮点数)等占位符
python
name = "hockor"
age = 18
print("Hello, %s! You are %d years old." % (name, age))
# 输出:Hello, hockor! You are 18 years old.
但是它的可读性确实太差了,一旦太长或者变量太多后面就写晕了,所以又衍生出来 format 方法
str.format()
python
name = "hockor"
age = 30
print("Hello, {}! You are {} years old.".format(name, age))
# 输出:Hello, hockor! You are 30 years old.
# 也可以添加关键字参数
print("Hello, {name}! You are {age} years old.".format(name="hockor", age=30))
这个比 % 更清晰,支持命名变量,同时支持格式化选项(如 .2f 保留两位小数),但是它的代码还是稍显冗长
f-string(3.6+版本支持)
下面这种就跟贴近 js 中的模板字符串语法了,但是 JS 中我们是用 ` 符号包裹的
python
name = "Charlie"
age = 35
print(f"Hello, {name}! You are {age} years old.")
# 输出:Hello, Charlie! You are 35 years old.
# 支持表达式
print(f"Next year, you will be {age + 1} years old.")
# 输出:Next year, you will be 36 years old.
# 支持格式化选项
price = 19.99
print(f"Price: ${price:.2f}") # 保留两位小数
# 输出:Price: $19.99
可以看到只需要在字符串前面添加一个f
关键字,就可以在后面的内容中直接使用大括号引用变量,比起前两种要方便的多。