Python3 基础

前言

终于开始正式学习 Python 了。近些年,Python 大火,互联网上下充斥着学了 Python 即可闯遍大江南北的口号与广告。

尽管在如此大环境之下,之前我也一直没想着接触 Python,因为我觉得对于 coder 来说,编程思想才是关键,语言这种东西一通百通,明白了基本语法,以及在尝试编写过程中逐步了解更多的语言特色与使用法则,基本不是难事,Python 尤是。

开始大创之后,对 Python 的接触时长大幅提升,是时候较为系统地了解一下 Python 的一些基础内容了。

目录

1. Python 简介

2. Python 特点

3. Python3 环境搭建 

4. Python3 基本语法

 

1. Python 简介

Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言,于 1989 年发明。

Python2 与 2020 年初停止更新,2.7 为最终版本。

Python3 简称为 Py3k,与 2008 年发布,不向下兼容,目前最新版本为 3.9。

这篇文章主要针对 Python3。

 

2. Python 特点

> 解释型语言

开发过程没有编译环节,类似于 PHP 与 Perl 等。

> 交互式语言

可以在 Python 提示符 >>> 后直接执行代码。

> 面向对象语言

支持面向对象风格或代码封装在对象的编程技术,同 C++ 与 Java 等。

> 初学者语言

初学者很容易上手,关键字少,结构简单,且支持广泛应用程序开发,从文字处理到浏览器到游戏等。

> 其他

标准库丰富,跨平台;可移植性、可扩展性强。

 

3. Python3 环境搭建

暂略。

 

4. Python3 基本语法

4.1. 关键字

Python 标准库提供了一个 keyword 模块,可以输出当前版本所有关键字:

>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

 

4.2. 标识符

标识符不能为关键字,第一个字符必须为大小写字母或下划线 _,对大小写敏感。可以用非 ASCII 字符(比如中文)作为标识符。

 

4.3. 注释

单行注释以 # 开头,多行注释以 ''' 或 """ 开始与结束。举例:

# 这是单行注释

'''
这是多行注释
'''

"""
这是多行注释
"""

尽管单引号与双引号版本效果相同,但在 PEP8 规范中建议双引号用于文档注释,而单引号用于类与对象内注释,一般也尽可能去遵循它;否则可能出现诸如 “Triple double-quoted strings should be used for docstrings. ” 的提示。

 

4.4. 行与缩进

4.4.1. 缩进

缩进是 Python 最具特色的内容之一。不同于 C, Java 等使用 {} 表示代码块,Python 直接用缩进表示,那么也就是说,缩进也是 Python 语法规范的一部分,如果缩进不符合规范,则可能出现语法错误,这也一定程度上对代码格式进行了规范。

如下代码被认为是不规范的:

if True:
    print(1)
else:
  print(0)

导致出现 “PEP 8: E111 indentation is not a multiple of four” 的提示。

如下代码被认为是语法错误:

a = 0
  b = 0

4.4.2. 多行语句

除了缩进有严格要求,Python 同样不允许同一条语句出现换行。但有时语句确实非常长,如果不换行,可读性很差,所以 Python 规定可以使用反斜杠 \ 表示长语句换行,例如:

total = alice + bob + \
        carol + dave + eve

注意,如果长语句包括于各种括号中(比如 [], (), {}),则不需要反斜杠。

4.4.3. 多条语句

多个语句可以写在同一行,中间用分号相隔。

 

4.5. 变量与基本数据类型

Python 中的变量不需要声明,在赋初值时就相当于同时声明了。同时,变量本身无需给出数据类型,我们所说的类型是指变量所指向的内存中对象的类型。

赋值使用等号 =,允许多个变量赋同一个值,允许一条语句为多个变量赋值,例如:

a = b = c = 1
a, b, c = 1, 2, 3

Python 有六大基本数据类型:Number(数字),String(字符串),List(列表),Tuple(元组),Set(集合),Dictionary(字典),下面依次介绍。

4.5.1. 数

数(Number),有四种类型:

int 整数,bool 布尔数,float 浮点数,complex 复数。例如:

a, b, c, d = 1, 2.0, True, 3 + 4j

它们分别对应如上四种数的类型。复数的实部与虚部均为浮点数,除了 a + bj 形式,还可以用 complex(a, b)。

Python 内置了 type 函数,用于查询变量所指的对象类型;以及 isinstance 函数,用于判定类型。例如:

print(type(a))
print(isinstance(a, float))

分别输出 <class 'int'> 和 False。

可以使用 del 语句来删除单个或多个对象。例如:

del a
del a, b

数值运算大同小异。其中,/ 表示非整除除法,// 表示整除,** 表示乘方。例如:

>>> 2 / 4  
0.5
>>> 2 // 4 
0
>>> 2 ** 5 
32

后面会有更多关于运算符的介绍。

整数还可以使用十六进制、八进制来表示。例如:

num1 = 0xABC
num2 = 0o566

4.5.2. 字符串

字符串(string),由一个或多个字符组成的一种数据类型。在 Python 中没有单独的字符类型,单字符即长度为 1 的字符串;同注释一样,单引号和双引号作用是相同的,同时,还可以使用三引号指定一个多行字符串。比如:

a = 'word'
b = "This is a sentence."
c = '''
paragraph 1
paragraph 2
'''

字符串中可以使用加号 +,表示直接相连;可以使用乘号 *,表示重复。比如:

d = 'outer' + 'wilds'
e = 'be' * 2

字符串中可以使用反斜杠 \,表示转义字符,如下为常用转义字符:

① \ + \ ' ''  输出后者字符

② \a  响铃

③ \b  退格

④ \n  换行

⑤ \r  回车

⑥ \t  横向制表符

⑦ \v  纵向制表符 

如果在字符串前加上 r 或 R(raw,未加工的),可使反斜杠不表示转义。

f = 'icpc\n2020'
g = r'icpc\n2020'

前者的 “icpc” 与 “2020” 之间为换行符 \n,后者则为 “icpc\n2020”。

字符串支持双向索引。除下标为 0 开始表示从左至右索引,还可以为负数,从 -1 开始表示从右至左索引。比如 a[-2] 表示字符串 a 的倒数第二个字符。

字符串输出时,可以只截取其中一部分,截取语法格式如下:

字符串变量名[下标]

表示截取指定下标的一个字符。

字符串变量名[头下标 : 尾下标 : 步长]

表示截取以一定步长从头下标至尾下标前一位(左闭右开)的字符串;步长为 n 时表示每间隔 n 个字符输出一个字符,当 n 为负数时,表示逆向截取。

其中,三个参数均可缺省。

> 步长可缺省,默认值为 1,缺省时第二个冒号同时省略;

> 头下标可缺省,默认值为 0;

> 尾下标可缺省,默认值为字符串长度;

第一个冒号无论如何均不可省略,否则可能与只输出一个字符的情况产生二义性。

例子如下:

a = 'word'
print(a[0])  # print w
print(a[0:2])  # print wo
print(a[-3:-1])  # print or
print(a[1:])  # print ord
print(a[:3])  # print wor
print(a[:])  # print word
print(a[1::2])  # print od

字符串不允许向某一个索引位置赋值,比如 a[1] = 'p' 之类的,属于不可变数据。

上面的截取方式不局限于字符串类型。

> 格式化

Python 支持格式化字符串的输出,类似于 C 中的 sprintf,格式为:

print(带格式化符号的字符串 % 格式化元组)

例如:

>>> print("Hello, %s(%d)!" % ('jinkun113', 2021))
Hello, jinkun113(2021)!

常用的格式化符号如下:

① %c 格式化字符及其 ASCII 码

② %s 格式化字符串

③ %d 格式化整数

④ %f 格式化浮点数

> str.format

Python 还提供了 str.format 函数,以增强格式化的功能,格式为:

带 {} 的字符串.format(格式化参数)

有如下几种不同的使用方式:

>>>"{} {}".format("Outer", "Wilds")  # 不设置指定位置,按默认顺序
'Outer Wilds'
 
>>> "{0} {1}".format("Outer", "Wilds")  # 设置指定位置
'Outer Wilds'
 
>>> "{1} {0} {1}".format("Outer", "Wilds")  # 设置指定位置
'Wilds Outer Wilds'

>>> "名称:{name}, 地址 {url}".format(name="jinkun113", url="www.runoob.com")
'名称:jinkun113, 地址 www.cnblogs.com/jinkun113'

dict = {"name": "jinkun113", "url": "www.cnblogs.com/jinkun113"}  # 使用字典来设置参数
list = ['jinkun113', 'www.cnblogs.com/jinkun113'] # 使用列表来设置参数

>>> "名称:{name}, 地址 {url}".format(**dict)
'名称:jinkun113, 地址 wwww.cnblogs.com/jinkun113'

>>> "名称:{0[0]}, 地址 {0[1]}".format(list)
'名称:jinkun113, 地址 www.cnblogs.com/jinkun113'

还有一系列格式化数字的方法:

① {:.*f} 保留小数点后 * 位

② {:x>*d} 向数字左侧填充 x,宽度为 *(改为 < 为右侧,缺省 x 时为直接左右对齐)

③ {:,} 改为逗号分隔式数字

④ {:.*%} 改为保留 * 位的百分比格式(改为 e 为科学计数法格式)

> f-string

Python 3.6 后的版本添加了 f-string,即字面量格式化字符串。

暂略。

4.5.3. 列表

列表(List),是 Python 中使用最频繁的数据类型,可以完成大多数集合类的数据结构的实现。列表中各个元素的类型可以不痛,支持数字、字符串甚至列表(即嵌套)。定义列表的一般格式如下:

列表名 = [元素 A, 元素 B, ...]

和字符串一样,列表可以被索引和截取,可以连接与重复,且语法格式一致,不再介绍。

举个例子:

List1 = [1, 'hello', 2.33, "It's me", 0]
List2 = [3, List1]
List3 = List1 * 2 + List2
>>> print(List1[1:5:2])
... print(List3)
['hello', "It's me"]
[1, 'hello', 2.33, "It's me", 0, 1, 'hello', 2.33, "It's me", 0, 3, [1, 'hello', 2.33, "It's me", 0]]

不同的是,列表的元素可以被改变,不论是单个元素还是截取区间的元素。

List 还内置了许多方法。暂略。

4.5.3. 元组

元组(Tuple)与列表类似,但是写在小括号中,且不能被修改。

尽管元组不可被改变,但它可以包含可变的对象,比如列表。

其诸多特性也相同于字符串与列表,不再赘述。

仅包含 1 个元素的元组比较特殊,需要在元素后添加一个逗号。例如:

Tuple1 = (2, )

没有逗号,则会被看作单个元素。

4.5.4. 集合

集合(Set)写在花括号中,和数学概念的集合一样,它是无序的,且重复的元素会被自动去掉。

定义集合有两种方式,如下:

Set1 = {1, '2', "88888"}
Set2 = set('shakalaka')
Set3 = set('balabala')

集合支持差集、并集、交集、非交集运算,如下:

>>> print(Set2 - Set3)
{'h', 's', 'k'}
>>> print(Set2 | Set3)
{'a', 'b', 'k', 'h', 's', 'l'}
>>> print(Set2 & Set3)
{'a', 'l'}
>>> print(Set2 ^ Set3)
{'b', 'k', 'h', 's'}

4.5.5. 字典

字典(Dictionary),也是无序的,并且其元素的值(Value)是通过键(Key)来获取,而非偏移量,类似于 C++ 中的 map(映射)。例如:

Dict1 = {}
Dict1['one'] = "1 - ONE"
Dict1[2] = "2 - TWO"

Dict2 = {'Name': 'J.K.', 'ID': 'jinkun113', 'Location': 'Beijing'}

>>> print(Dict1[2])
2 - TWO
>>> print(Dict1.keys())
dict_keys(['one', 2])
>>> print(Dict1)
{'one': '1 - ONE', 2: '2 - TWO'}
>>> print(Dict2['ID'])
jinkun113
>>> print(Dict2.values())
dict_values(['J.K.', 'jinkun113', 'Beijing'])

字典和集合一样是使用花括号,不同的是字典需要同时定义键与值;同时需要注意的是,如果是直接使用 {},则表示建立的是空字典,而非空集合,空集合只能使用 set() 来建立。

字典还可以使用构造函数 dict() 来建立,例如:

>>> dict([('ONE', 1), ('TWO', 2), ('THREE', 3)])
{'ONE': 1, 'TWO': 2, 'THREE': 3}
>>> {x: x ** 2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
>>> dict(ONE=1, TWO=2, THREE=3)
{'ONE': 1, 'TWO': 2, 'THREE': 3}

4.5.6. 数据类型转换

数据类型转换很简单,直接将类型名作为函数名即可,例如:

a = 123

>>> print(float(a))
123.0
>>> print(hex(a))
0x7b
a = [1, 2, '3', 2]

>>> print(tuple(a))
(1, 2, '3', 2)
>>> print(set(a))
{1, 2, '3'}

 

4.6. 运算符及其优先级

运算符分为如下七类:

算数、关系、赋值、逻辑、位、成员、身份运算符。

其中大部分都无需在介绍,仅介绍在 Python 中比较特别的。

4.6.1 运算符

> 逻辑运算符 and / or / not

a = 1
b = 2

>>> print(a and b)
2
>>> print(a or b)
1
>>> print(not a)
False

> 成员运算符 in

a = 1
b = 2
c = 3
List5 = {1, 3, 5}
>>> print(a in List5)
True
>>> print(b in List5)
False
>>> print(c not in List5)
False

> 身份运算符 is

is 与 == 类似,后者为判断变量引用对象的值是否相等,而前者判断变量引用的是否为同一个对象。Python 提供 id 函数,用于获取对象的内存地址,也就是说,x is y 等价于 id(x) == id(y)。例如:

a = [1, 2, 3]
b = a
c = a[:]

>>> print(b is a)
True
>>> print(b == a)
True
>>> print(c is a)
False
>>> print(c == a)
True

Python 对较小的数有优化机制,-5 到 256 区间内的所有数会被预先创建,并存在一个固定的内存空间上;创建变量时如果初值为这个区间的数,则其指向的内存地址也会是一样的。并且,对于使用分号间隔的多条语句,如果有多个变量的初值相同,其内存地址也会指向相同位置。例如:

a = 10
b = 10

>>> print(a is b)
True
a = 1000
b = 1000

>>> print(a is b)
False
a = 1000; b = 1000

>>> print(a is b)
True

4.6.2. 优先级

从高到低依次为:

① **

② ~ + -(一元加减法)

③ * / % //

④ + -

⑤ << >>

⑥ &

⑦ ^ |

⑧ <= < > >=

⑨ == !=

⑩ = %= /= //= -= += *= **=

⑪ is is not

⑫ in not in

⑬ not and or

 

4.7. print 输出

Python 使用 print 函数来输出,上面已经演示了。默认情况下输出是换行的,如果不换行,则加上第二个参数 “end='*'”,如下:

print(1, end='')
print(2, end=',')

 * 可缺省,即只起到不换行的作用;非缺省时,则是在输出内容后自动添加指定字符 *。

后面将有更多关于输入和输出的介绍。

 

4.8. 条件与循环语句

4.8.1. if 语句

Python 中,条件语句仅有 if 一种,没有 switch - case 语句。

else if 在 Python 中被精简为 elif,所以关键字为 if - elif - else。

用冒号 : 来表示语句块的开始,用缩进来划分语句块,下同。

当 if 语句块中仅有一条语句时,可以将该语句直接接在 : 之后,下同。

4.8.2. while 语句

Python 中没有 do - while 循环。

while 后面可以接 else,表示 while 中的条件语句为 False 时执行的内容。

4.8.3. for 语句

for 可以遍历任何序列中的项目,如果是数字序列,则使用内置的 range() 函数,其三个参数和字符串截取相同,即首尾与步长,此处略;而如果只有一个参数 x,则表示从 0 到 x - 1 的序列。

举个例子:

for i in range(1, 10, 2): print(i)

循环语句同样可以使用 break 和 continue。

4.8.4. pass 语句

Python 提供 pass 语句,表示空,不做任何事情,一般用作占位,可以保持程序结构的完整性。

4.9. 迭代器与生成器

4.9.1. 迭代器

Python 提供迭代器(Iterator),以遍历字符串、列表或元组对象的元素。它从第一个元素开始访问,直到最后,只能往前遍历。其两大基本方法:iter() 和 next(),分别表示创建迭代器对象与返回迭代器下一个元素。举个例子:

list=[1,2,3,4]
it = iter(list)

>>> print(next(it))
1
>>> print(next(it))
2

迭代器对象可以使用 for 语句进行遍历。

迭代器可以通过类进行自定义,在下面的面向对象部分中会提到。

4.9.2. 生成器

在 Python 中,使用了 yield 的函数被称为生成器(Generator),其返回的不是值,而是迭代器。在调用过程中,每次遇到 yield 语句时,函数会暂停并保存当前所有运行信息,返回 yield 的值,并在下一次执行 next() 时从当前位置继续执行。

下面是使用生成器实现的 Fibonacci 数列的代码: 

def fibonacci(n):
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1

f = fibonacci(10)
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

 

4.10. 函数

函数是组织好的、可重复使用的代码段。Python 中有许多内建函数,比如 print(),同样可以自定义函数,以关键词 def 开头。

和变量一样,Python 的函数没有规定返回类型。

关于参数,Python 允许设置默认参数,以关键字来传入参数值,允许参数个数不定长(在固定函数后加上一个带星号 * 的元组以存放所有未命名的参数,或者带两个星号 ** 表示以字典形式导入)。

Python 提供 lambda 函数,来创建匿名函数,其只是一个表达式,比 def 形式简单。比如:

c = lambda a, b: a + b

 

4.11. 数据结构

由于 Python 内置了诸如列表、元组、集合、字典等数据类型,所以要使用数据结构时尤为轻松。

对于列表,其内置有如下方法:

> list.append(x)  将 x 添加到列表的末尾

> list.extend(L)  将列表 L 添加到该列表的末尾

> list.remove(x)  删除列表中值为 x 的第一个元素;如果不存在则会返回错误

> list.pop(x)  删除列表中位置为 x 的元素,并返回该值;可缺省,表示最后一个元素

> list.clear()  删除列表中的所有项,等价于 del a[:]

> list.index(x)  返回列表中值为 x 的第一个元素的索引;如果不存在则会返回错误

> list.count(x)  返回值为 x 的元素的个数

> list.sort(cmp=None, key=None, reverse=False)  对列表元素进行排序,默认为升序排序,cmp 表示排序参数,key 表示用来比较的元素名,reverse 为 True 时为降序。

> list.reverse()  将列表中的元素倒序

> list.copy()  返回列表的浅复制(浅复制表示两个对象指向同一内存地址,对应概念为深复制)

根据上述方法,将列表当做栈来使用就非常方便了,借助 append 和 pop 即可实现;队列其实也好实现,但效率并不高。

 

4.12. import 与模块

Python 使用 import 或者 from...import 语句来导入模块。

将整个模块导入,使用 import,例如:

import sys

将某个模块的一个、多个或全部函数导入,使用 from...import,例如:

from sys import argv
from sys import argv, path
from sys import *

将整个模块导入和将模块的全部函数导入并非等价。前者相当于导入该文件夹,后者相当于导入文件夹内所有文件;所以,前者在引用其中函数时需要加上模块名,后者则可以直接使用。

 

4.13. 输入输出与文件 File

4.13.1. 读取键盘输入

Python 内置了 input() 函数,以从标准输入读入一行文本,默认标准输入是键盘。可以填入需要展示在标准输入上的内容,例如:

>>> str = input("name: ")
name: 

输出函数 print() 上面已经介绍了。

4.13.2. 读写文件

Python 内置了 open() 函数,以对一个 file 对象即文件,进行访问。一般格式如下:

open(file, mode='r')

而完整格式其实如下:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

参数说明:

> file  唯一必需,表示文件路径(相对或绝对均可)

> mode  文件打开模式

下面是模式与功能的对应关系。

rb, rb+, wb, wb+, ab, ab+ 模式在原基础上加上 b,表示以二进制格式打开。

> buffering  设置缓冲

> encoding  编码方式,一般为 UTF-8

> errors  报错级别

> newline  区分换行符

> closefd  传入的 file 参数类型

> opener  自定义开启器

对于 file 对象,有如下方法:

> file.read(size)  读取文件中大小为 size 的数据,返回一个多行字符串;size 如果缺省或为负数,则读取所有数据

> file.readline()  读取文件中单独的一行数据,以换行符 \n 结束,返回一个字符串

> file.readlines()  读取文件中每一行的数据,返回一个列表

> file.write(str)  将 str 写入到文件中,并返回字符数

> file.tell()  返回文件对细想当前所处位置,即从文件开头开始算起的字节数

> file.seek(a, b)  改变文件当前位置,当 b = 0 时,从文件首字母往后移动 a 个字符;b = 1 时,从当前位置往后移动 a 个字符;b = 2 时,从结尾位置往前移动 -a 个字符。  

> file.close()  关闭文件,并释放系统资源;

举个例子:

f = open("1.txt", "w")
f.write("Hello, world!")
f.close()

 

4.14. 系统 OS

Python 提供了 os 模块,里面有丰富的方法来处理文件与文件目录。常用方法如下:

> os.access(path, mode)  检验权限模式

> os.chdir(path)  改变当前工作目录

> os.chmod(path, mode)  更改权限

> os.chchown(path, uid, gid)  更改文件所有者

> os.close(fd)  关闭文件描述符 fd

> os.listdir(path)  返回 path 指定的文件夹包含的文件和文件夹的名字的列表

> os.makedirs(path, mode)  递归文件夹创建函数,mkdir 方法类似,

4.16. 错误与异常

4.17. 面向对象

4.18. 标准库一览

 

4. 命令行参数

 

posted @ 2021-01-08 00:18  jinkun113  阅读(347)  评论(3编辑  收藏  举报