5826 字
29 分钟
【Python】基础语法介绍
2023-02-25
2023-03-02

前言#

这一篇为 python 的基础语法部分,作为入门,本章是基于具有其他语言学习基础的情况下快速理解 python 基础语法而写的,对于基础语法不会有解释。

PS:部分附带 C/C++ 对照。


基础语法#

基础元素#

基本结构#

python 中把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为 模块(module)。模块是一个包含所有你定义的函数和变量的文件,其后缀名是 .py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。

除了模块,python 最具特色的就是使用缩进来表示代码块,不需要使用大括号 {}。因此 python 对于换行的要求很高,一行语句的结尾不需要结尾符号

当然,如果想一行执行多条语句,语句之间还是需要使用分号 ; 分割,例如:

x = 1; print(x)

最后语句结尾没有符号。

缩进的空格数是可变的,但是 同一个代码块的语句必须包含相同的缩进空格数。例如:

if True:
print("Answer")
print("True")
else:
print("Answer")

其中同一缩进的代码在同一代码块中。

变量#

python 中的变量命名方式与其他语言相同,变量用小写字母开头是 Python 的惯例。变量名只能包含 字母、数字和下划线。变量名能以字母或下划线开头,但 不能以数字开头

一般使用驼峰型命名,例如:linkListed_smaphello_2

常量#

python 中的常量大部分与变量相同,但常用 全大写 作为命名,例如:PAIMAX_NUMBER

变量与常量的定义#

我们在定义时,遵循这样的规则:<identifier> = <expression>

变量与常量同样有数据类型,如:整型(int),浮点型(float),字符串(string)。注意,python 中使用了字符串代替字符类型,任何一个字符都是字符串。

Python 可以使用引号()、双引号()、三引号('''""")来表示字符串,引号的开始与结束必须是相同类型的。

其中三引号可以由多行组成,编写多行文本的快捷语法,常用于文档字符串,在文件的特定地点,被当做注释。

根据命名规则,与 C/C++ 不同的是 python 变量与常量的定义不需要标注它的类型,或者说 python 定义变量和常量时的变量类型是 auto 的。这就要求 必须在定义变量或常量时初始化 它,赋予它数据类型。例如:

name = "Hoyue" # 字符串型
stuID = 10000 # 整数型
marks = 99.99 # 浮点型
MAX_MARKS = 100.0 # 常量(浮点)

我们还可以同时给多个变量赋值,用逗号将变量名分开;对于要赋给变量的值,也需同样处理。Python 将按顺序将每个值赋给对应的变量。只要变量和值的个数相同,Python 就能正确地将它们关联起来。

# 同时给三个变量赋值同样的类型
x, y, z = 0, 0, 0
# 同时给三个变量赋值不同类型
x, y, z = 0, 1.1, "str"

与 C/C++ 不同的是,python 支持同时给多个变量赋予不同类型的值

根据这个多个变量赋值的规则,我们还可以实现快速交换值。在 C/C++ 中通常需要定义第三个变量进行存储,而 python 中可以 通过逗号进行快速交换,例如:

a, b = b, a

注释#

在 Python 中,注释用井号(#)标识。井号后面的内容都会被 Python 解释器忽略。Python 也会忽略注释之后的空行。

例如:

# This program says hello and asks for my name.

当然这只是单行的注释,我们需要多行注释时需要使用三引号(''')包含,例如:

"""这是一个注释。
包含了多个语句"""

运算符#

Python 表达式中可以使用大量其他操作符。例如:

operators


函数调用#

调用函数与 C/C++ 中一样,使用 function_Name() 表示,例如:

max(1, 2)

print() 函数将括号内的字符串显示在屏幕上。print() 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="",例如:

x, y = 1, 2
print(x)
print(y)
print(x, end=" ")
print(y, end="")

最后我们的输出为:

1
2
1 2

end=" " 表示了结尾由空格符表示,如果这里中间没有空格,则最后输出为:12

import 语句#

正如 C/C++ 中的 include 语句一样,python 执行 import 语句可以引入模块。当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。将 整个模块(somemodule)导入,格式为:

import module1, module2, moduleN

例如,想要导入模块 math,需要把命令放在脚本的顶端:

import math

一个模块只会被导入一次。使用导入的模块的函数,必须使用成员函数的形式进行调用,例如调用 sqrt() 函数:

import math
a = 4
b = math.sqrt(a)

如果不想以这样的形式调用,我们还可以使用下面的方法引入模块中的函数:

  • 从某个模块中导入某个函数,格式为:from somemodule import somefunction
  • 从某个模块中导入多个函数,格式为:from somemodule import firstfunc, secondfunc, thirdfunc
  • 将某个模块中的全部函数导入,格式为:from somemodule import *

这样的引用,模块内函数就不需要使用 模块.函数() 的形式调用了,直接使用 函数() 调用即可。例如:

from math import sqrt
y = sqrt(4) # 仅 sqrt() 可以这样调用
from math import *
y = sqrt(4) # math 中所有的函数都可以直接调用

input() 函数#

函数等待用户在键盘上输入一些文本,并按下回车键。例如:

myName = input()

我们输入的值会赋值给 myName

判断语句#

我们的判断语句基本逻辑与 C/C++ 中一样,Python 条件语句是通过一条或多条语句的执行结果(True 或者 False)来决定执行的代码块。

Python 中 if 语句的一般形式如下所示:

if condition_1:
statement_block_1
elif condition_2:
statement_block_2
else:
statement_block_3

Python 中用 elif 代替了 else if,所以 if 语句的关键字为:if – elif – else。我们还需要注意下面几点:

  1. 每个条件后面要使用冒号 :,表示接下来是满足条件后要执行的语句块。
  2. 使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块
  3. else 与 elif 只对应离它最近的 if 或 elif 语句
  4. 在 Python 中 没有 switch...case 语句

虽然没有 switch...case 语句,但 在 python 3.10 以上版本,增加了 match...case 的条件判断(使用时请注意你的 python 版本)。

match subject:
case <pattern_1>:
<action_1>
case <pattern_2>:
<action_2>
case <pattern_3>:
<action_3>
case _:
<action_wildcard>

match 后的对象会依次与 case 后的内容进行匹配。如果匹配成功,则执行匹配到的表达式,否则直接跳过,_ 可以匹配一切,相当于 default:

循环语句#

Python 中的循环语句有 for 和 while。Python 中 while 语句的一般形式与其他语言基本一致:

while condition:
statements……

同样需要注意冒号和缩进。另外,在 Python 中没有 do..while 循环。

while 可以和 else 组合,条件语句为 false 时,则执行 else 的语句块。例如:

while <expr>:
<statement(s)>
else:
<additional_statement(s)>

expr 条件语句为 true 则执行 <statement(s)> 语句块,如果为 false,则执行 <additional_statement(s)>。这样的写法一般 当循环代码块中定义的变量需要进行最后地操作时才使用

类似 if 语句的语法,如果你的 while 循环体中只有一条语句,你可以将该语句与 while 写在同一行中,如下所示:

x = 1
while(x): print(x)

Python for 循环可以遍历任何可迭代对象,如一个列表或者一个字符串。

for 循环的一般格式如下:

for <variable> in <sequence>:
<statements>
else:
<statements>

如果要表示不在 <sequence> 中,可以改为 <variable> not in <sequence>

我们经常使用 for 循环在一个范围内迭代,例如:for number in range(1, 6):

和 while 一样,在 Python 中,for...else 语句用于在循环结束后执行一段代码。

for item in iterable:
# 循环主体
else:
# 循环结束后执行的代码

如果你需要遍历数字序列,可以使用内置 range() 函数。它会生成从 0 开始的数列。我们想让数列元素为 n 个,则为 range(n),例如 range(5) 表示 {0,1,2,3,4}。如果你需要的是一个区间从 n 到 m 的数列,则 range(n, m+1) 而不是 range(n, m),因为 range(n, m) 表示 {n, n+1, ..., m-2, m-1}不包括最后一位 m

如果你的迭代不是 1,我们可以在第三个参数处添加迭代数。例如 range(n, m, x) 指从 n 到 m-1 的数列,每次递增 x 位。

循环中 break 和 continue 语句与 C/C++ 一致。

  • break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
  • continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环。

数据结构#

python 中有六个标准的数据类型:

  • Number(数字)
  • String(字符串)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

数字包含了:int、float、bool、complex(复数),关于数字的操作,和平时的操作一样。

字符串#

字符串用单引号 ' 或双引号 " 括起来,同时使用反斜杠 \ 转义特殊字符。同时字符串也可以看成是字符数组,满足 变量[下标]变量[头下标:尾下标] 的形式,例如:

s = 'Python'
print(s) # 输出字符串
print(s[0:-1]) # 输出第一个到倒数第二个的所有字符
print(s[0]) # 输出字符串第一个字符
print(s[2:5]) # 输出从第三个开始到第五个的字符
print(s[2:]) # 输出从第三个开始的后的所有字符

python 中允许下标为负,当下标为负时即从后面开始引索,如图:

string-index

python 的字符串运算可以使用一些特殊的符号,例如 +*\

加号 + 是字符串的连接符,星号 * 表示复制当前字符串,与之结合的数字为复制的次数。例如:

print(s * 2) # 输出字符串两次,也可以写成 print(2 * s)
print(s + "TEST") # 连接字符串

Python 使用反斜杠 \ 转义特殊字符,或者在句尾使用续行符 \,表示下一行是上一行的延续。如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r 或者再加一个反斜杠:

print("Pyth\non") # 转义
# Pyth
# on
print(r"Pyth\non") # 原样输出
# Pyth\non
print("Pyth\\non") # 原样输出
# Pyth\non
print("Hoyue T\
est") # 续行符
# Hoyue Test

与 C/C++ 字符串不同的是,Python 字符串内部是个 const 不能被改变。例如:

/* C 或 C++ 形式 */
char *str1 = "testA";
str1 = 'B'; // OK,可以修改
printf("%s", str1); // 最后输出为 testB
# Python 形式
str2 = "testC"
str2 = "D" # ERROR,python 字符串无法修改字符

字符串有一些方法或成员函数可以使用,与列表的方法基本一致,具体看列表的方法,以及字符串特殊的方法请查说明。

列表#

List(列表)是 Python 中使用最频繁的数据类型,相当于 C/C++ 中的数组。列表可以完成大多数集合类的数据结构实现。与 C/C++ 不同的是,列表中元素的类型可以不相同,它支持数字、字符串甚至可以包含列表。

列表是写在方括号 [] 之间、用逗号分隔开的元素列表。和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。例如:

lst = ['a', 'b', 'c', 'd', 'e']
print(lst) # 输出完整列表
print(lst[0]) # 输出列表第一个元素
print(lst[1:3]) # 从第二个开始输出到第三个元素
print(lst[2:]) # 输出从第三个元素开始的所有元素
print(lst * 2) # 输出两次列表
print(lst + lst[2:4])# 连接列表

list-demo

Python 列表截取格式为:变量[头下标:尾下标],它同时可以接收第三个参数,参数作用是截取的步长。

与 C++ 中一样,python 列表也可以看成是类,并拥有一些方法(成员函数)与特定函数:

列表常用方法:

序号方法说明
1list.append(obj)在列表末尾添加新的对象
2list.count(obj)统计某个元素在列表中出现的次数
3list.extend(seq)列表末尾一次性追加另一个序列中的多个值
4list.index(obj)找出某个值第一个匹配项的索引位置
5list.insert(index, obj)将对象插入列表
6list.pop([index=-1])移除并返回指定位置(默认最后一个)的元素
7list.remove(obj)移除列表中某个值的第一个匹配项
8list.reverse()原地反转列表
9list.sort(key=None, reverse=False)对原列表进行排序
10list.clear()清空列表
11list.copy()复制列表

列表相关内置函数:

序号函数说明
1len(list)列表元素个数
2max(list)返回列表元素最大值
3min(list)返回列表元素最小值
4list(seq)将元组转换为列表

元组#

Python 的元组与列表类似,不同之处在于元组的 元素不能修改元组使用小括号 ( ),列表使用方括号 [ ]。元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。例如:

tup = (1, 2, 3, 4, 5)

创建空元组时直接 () 即可,但当创建的元组只有一个元素时,需要在一个元素后加 , 防止被识别为其他类型变量:

tup1 = (50) # 不加逗号,类型为整型
tup1 = (50,) # 加上逗号,类型为元组

其他基本操作与列表基本一致,除了 元组中的元素值是不允许修改 外。

字典#

字典是另一种可变容器模型,且可存储任意类型对象。字典由关键字 key,值 value 组成。字典的每个键值 key => value 对用冒号 : 分割,每个对之间用逗号 , 分割,整个字典包括在花括号 {} 中。

d = { "key1": value1, "key2": value2, "key3": value3 }

关键字必须是唯一的,但值则不必。值可以取任何数据类型,但键必须是不可变的,如字符串、数字。例如:

d = {'name': 'hoyue', 'likes': 999, 'url': 'hoyue.fun'}

注意 dict 作为 Python 的关键字和内置函数,变量名不建议命名为 dict

我们可以用大括号 {} 或是函数 dict() 创建字典:

emptyDict1 = {} # 新建空字典
emptyDict2 = dict() # 函数形式新建字典

当我们输出值的时候,需要输出的变量为 d[key]

注意:不允许同一个关键字出现两次。创建时如果同一个关键字被赋值两次,之后记住最后赋值的。关键字必须不可变,所以可以用数字、字符串或元组充当,而用列表就不行

Python 字典常用方法:

序号方法/函数说明
1dict.clear()删除字典内所有元素
2dict.copy()返回一个字典的浅复制
3dict.fromkeys(seq, val=None)用序列 seq 中元素做键,val 为初始值创建新字典
4dict.get(key, default=None)返回指定键的值,不在则返回 default
5key in dict键在字典里返回 True,否则返回 False
6dict.items()以列表返回一个视图对象(键值对)
7dict.keys()返回一个视图对象(键)
8dict.setdefault(key, default=None)键不存在则添加并设为 default,返回对应值
9dict.update(dict2)dict2 的键/值对更新到当前字典
10dict.values()返回一个视图对象(值)
11dict.pop(key[, default])删除并返回键对应的值
12dict.popitem()返回并删除字典中的最后一对键和值

集合#

集合(set)和我们数学中学的一样,是一个无序的不重复元素序列。我们可以使用大括号 {} 或者 set() 函数创建集合。例如:

basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
thisset = set(("Google", "Runoob", "Taobao"))

但是,创建一个空集合必须用 set() 而不是 {},因为 {} 是用来 创建一个空字典

它满足集合的基本操作:交、并、差、异或

A = {'a', 'r', 'b', 'c', 'd'}
B = {'a', 'l', 'c', 'm', 'z'}
A - B # 差集:A 中有而 B 没有
# {'r', 'd', 'b'}
A | B # 并集
# {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
A & B # 交集
# {'a', 'c'}
A ^ B # 对称差(异或)
# {'r', 'd', 'b', 'm', 'z', 'l'}

将元素 x 添加到集合 s 中,我们一般使用 add()update() 方法。如果元素已存在,则不进行任何操作。

s = set(("Google", "Baidu", "Yandex"))
s.add("Bing") # 一般用来添加单个元素
s.update({1, 3}) # 可以添加集合、列表、元组等
# {1, 3, 'Baidu', 'Bing', 'Google', 'Yandex'} # 字典序排序

与添加元素对应的就是删除元素,我们一般使用 remove()discard() 方法,其中若元素不存在,remove() 会报错,discard() 不会。

s = {1, 3, 'Baidu', 'Bing', 'Google', 'Yandex'}
s.remove('Bing') # 删除存在的元素
s.discard('Google') # 删除存在的元素
# s.remove('Twitter') # ERROR:不存在,报错
s.discard('Facebook')# 不存在,不报错

我们还常用 len(s) 计算长度,s.clear() 清除整个集合。


函数定义#

函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段。

普通函数#

定义一个函数时,函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。函数内容以冒号 : 起始,并且缩进

不像 C/C++,python 的函数 不需要定义返回值类型。用 return [表达式] 结束函数,选择性地返回一个值给调用方,此时返回的类型为 auto,不带表达式的 return 相当于返回 None

def 函数名(参数列表):
函数体

例如:

def max2(a, b):
if a > b:
return a
else:
return b

对于参数传递,就像 C/C++ 中一样,分为:

  • 不可变类型: 类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
  • 可变类型: 类似 C++ 的引用传递,如列表、字典。如 fun(la),将 la 真正地传过去,修改后 fun 外部的 la 也会受影响。

递归函数#

对于递归函数,和 C/C++ 一样,我们只需要自己调用自己即可,例如计算阶乘:

def recursive_fact(n):
if n <= 1:
return n
return n * recursive_fact(n - 1)

类定义#

类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。

类的定义如下:

class ClassName:
<statement-1>
.
.
.
<statement-N>

类对象支持两种操作:属性引用和实例化。属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name。例如,创建类和对象:

class MyClass:
i = 12345
def f(self):
return 'hello world'
# 实例化类
x = MyClass()
y = x.f()

此时 xMyClass() 的一个对象,y 为类对象的方法返回值。因为没有传入参数,故 x 为一个空的对象(仅类默认属性)。

类的属性#

类的属性即类中的变量,它又可以分为公共(公有,public)属性和私有(private)属性。在 C++ 中,我们需要定义 publicprivate 下的变量,而在 python 中,我们把公有属性正常定义,私有属性定义时,在属性名或方法名前增加两个下划线,就定义为了私有属性。例如:

class People:
name = ''
__age = 18
def __init__(self, n):
self.name = n

其中,name 为公有属性,__age 为私有属性。私有属性外部不能访问;在对象的方法内部是可以访问私有属性的。

类的方法#

在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。

与私有属性一样,在方法定义前加上两个下划线可以定义私有方法,外部不能访问私有方法。

构造方法#

类有一个名为 __init__() 的特殊方法,该方法在类实例化时会自动调用,相当于 C++ 中类的构造函数(constructor),但不同的是,__init__() 可以省略,省略时对象定义为空。例如:

def __init__(self):
self.data = []

类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照惯例它的名称是 selfself 表示当前对象的引用,但它不是关键字,你可以改变它的名字(不推荐)。

类的继承#

Python 同样支持类的继承,派生类的定义如下所示:

class DerivedClassName(BaseClassName):
<statement-1>
.
.
.
<statement-N>

子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。Python 同样有限的支持多继承形式:

class DerivedClassName(Base1, Base2, Base3, ...):
<statement-1>
.
.
.
<statement-N>

需要注意圆括号中父类的顺序。若是父类中有相同的方法名,而在子类使用时未指定,python 从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。

class Parent: # 定义父类
def myMethod(self):
print('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print('调用子类方法')

析构函数与其他特殊方法#

__del__ 析构函数,释放对象时使用(与构造函数一样,可以没有)。

除了这些外,还有这些类的专有方法(常见重载点):

  • __init__ 构造函数,在生成对象时调用
  • __del__ 析构函数,释放对象时使用
  • __repr__ 打印、转换
  • __setitem__ 按照索引赋值
  • __getitem__ 按照索引获取值
  • __len__ 获得长度
  • __cmp__ / 比较相关: 比较运算(__lt__/__le__/__eq__/__ne__/__gt__/__ge__
  • __call__ 使实例可调用
  • __add__ / __sub__ / __mul__ / __truediv__ / __mod__ / __pow__ 算术运算重载

运算符重载#

Python 同样支持运算符重载,我们可以对类的专有方法进行重载。例如:

class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return f'Vector ({self.a}, {self.b})'
def __add__(self, other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2) # Vector (7, 8)
【Python】基础语法介绍
https://hoyue.fun/python_basic.html
作者
Hoyue
发布于
2023-02-25
最后更新于
2023-03-02
许可协议
CC BY-NC-SA 4.0
评论