这篇博文主要介绍 Python3 的一些常用语法,因为大部分基础语法在廖雪峰大神的 Python 教程 都有详细的介绍,此文主要介绍一些常用的入门知识,并提供详细知识点的学习链接。
输入&输出
输出
用 print()
在括号中加上字符串,就可以向屏幕上输出指定的文字,print()
方法支持可变参数,支持同时打印多个值,用逗号隔开,遇到逗号时会输出一个空格。
'The quick brown fox', 'jumps over', 'the lazy dog') > print( |
print()
还可以直接打印表达式的运算结果
>>> print('100 + 200 =', 100 + 200) |
输入
之所以把输入放到输出的后面,是因为就爬虫而言,输入实在很少用,即使有定制的需求,通常也是通过读取配置文件实现。笔者目前唯一用到输入的功能,就是在程序运行结束后等待用户输入确认再退出程序,避免程序运行结束后自动退出,因为自动退出会让用户误以为是闪退。
有需要了解输入部分的请看这里,把下面的代码加到程序最后就可以等待用户确认后再退出程序:
input('enter anything to exit: ') |
当然也可以通过线程睡眠达到这个效果,但是笔者认为它即麻烦又不够友好,并不建议使用。
数据类型和变量
Python 基础数据类型包括 int、float、str、bool、None,分别是整形、浮点型、字符串、布尔值、空值。
其中整形和浮点型不多介绍,跟其他语言差别不大。
字符串表示
字符串可以用单引号或双引号括起来,具体使用哪个看个人习惯或团队约定,建议是单个项目使用统一的约定。如果字符串内部既包含 '
又包含 "
,Python 的处理和大部分语言一样,可以在引号的前面加上转义字符 \
来标识。
如果字符串里面有很多字符都需要转义,就需要加很多 \
,为了简化,Python还允许用 r''
表示 ''
内部的字符串默认不转义:
'\\\t\\') print( |
如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许用 '''...'''
的格式表示多行内容:
print('''line1 |
多行字符串 '''...'''
还可以在前面加上 r
使用。
布尔值
布尔值只有 True
和 False
两种值,可以用 and
、or
、not
对布尔值进行运算操作,这相对于其他语言来说比较奇葩,不过也不是很难接受:
True or True |
布尔值经常用于条件判断:
if age >= 18: |
空值
空值是 Python 里一个特殊的值,用 None
表示。None 不能理解为0,因为0是有意义的,而 None 是一个特殊的空值。
变量
变量名必须是大小写英文、数字和 _
的组合,且不能用数字开头。
可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量。
a = 123 # a是整数 |
这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。
对于动态语言的这种特性是好是坏,笔者无法做出断言,不过建议不要随意修改变量的类型,这会导致出错从概率变大,而且不易维护。
常量
所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量:
PI = 3.14159265359 |
但事实上PI仍然是一个变量,Python根本没有任何机制保证PI不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量PI的值,也没人能拦住你。
字符串操作
编码转换
前文已经提过,在最新的 Python 3 版本中,字符串 str 是以 Unicode 编码的,通过 encode()
方法可以将 str 编码为指定的 bytes,例如:
'ABC'.encode('ascii') > |
反过来,要把 bytes 变为 str,就需要用 decode()
方法,例如:
'ABC'.decode('ascii') > b |
由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:
|
第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
申明了UTF-8编码并不意味着你的.py文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用 UTF-8 without BOM 编码
长度计算
要计算str包含多少个字符,可以用len()函数,len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:
'ABC') > len(b |
格式化
在Python中,采用的格式化方式和C语言是一致的,用 %
实现
'Hello, %s' % 'world' > |
常见的占位符有:
占位符 | 说明 |
---|---|
%d | 整数 |
%f | 浮点数 |
%s | 字符串 |
%x | 十六进制整数 |
其中,格式化整数和浮点数还可以指定是否补0和整数与小数的位数:
>>> '%2d-%02d' % (3, 1) |
如果你不太确定应该用什么,%s
永远起作用,它会把任何数据类型转换为字符串:
>>> 'Age: %s. Gender: %s' % (25, True) |
如果要在字符串里显示 % ,可以用 %% 表示:
'growth rate: %d %%' % 7 > |
匹配和搜索文本
'yeah, but no, but yeah, but no, but yeah' text = |
字符串拼凑
str 支持 +、+= 运算符:
'a' > s1 = |
字符串分割、合并
'my name is python' > s = |
字符串替换
>>> text = 'yeah, but no, but yeah, but no, but yeah' |
去除两侧字符
' test ' > s = |
正则表达式
正则表达式的使用见这个教程,需要注意的是正则规则使用 r''
格式的字符串,可以减少大量的转义字符。
这边只介绍简单的字符提取,提取结果是 None or 字符串数组:
result = re.findall(r'(?<=uploads)/.*', url) |
list & tuple
list
list是一种有序的集合,可以随时添加和删除其中的元素。
初始化和检索
'Michael', 'Bob', 'Tracy'] > classmates = [ |
下标为负数时表示逆向检索,下标越界会导致崩溃
插入、删除、替换元素
'Adam') > classmates.append( |
tuple
tuple和list非常类似,但是tuple一旦初始化就不能修改。
'Michael', 'Bob', 'Tracy') > classmates = ( |
不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
一个空的tuple:
> t = () |
一个只有1个元素的tuple:
1,) > t = ( |
Why?
这是因为括号 ()
既可以表示 tuple,又可以表示数学公式中的小括号,这会导致 (1)
产生歧义,因此,Python 规定,(1)
按小括号进行计算,表示只有一个元素的 tuple 时,加上逗号来消除歧义。
dict & set
dict
Python内置了字典 dict 的支持,dict 全称 dictionary,在其他语言中也称为 map,使用键-值(key-value)存储,具有极快的查找速度。
dict的key必须是不可变对象,这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。
初始化和检索
'Michael': 95, 'Bob': 75, 'Tracy': 85} > d = { |
检索时如果 key 不存在就会报错:
'Thomas'] > d[ |
有两个方案可以解决这个问题,一个是取值之前使用 in
判断 key 是否存在,另一个是用 get()
方法取值,其中 get()
方法在查找失败时,默认返回 None, 也可以指定 Value。
'Thomas' in d > |
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key,重复元素在set中自动被过滤。
初始化、检索set
>>> s = set([1, 1, 2, 2, 3, 3]) |
添加、删除元素
>>> s.add(4) |
交集、并集
>>> s1 = set([1, 2, 3]) |
注意:返回None的时候Python的交互式命令行不显示结果。
插入、删除、替换元素
'Adam'] = 67 > d[ |
条件判断
if
语句的形式:
if <x1>: |
只要x
是非零数值、非空字符串、非空list、非空tuple、非空dict、非空set、非None等,就判断为True,否则为False。
if []: |
循环
for x in ...
循环
sum = 0 |
用 range()
生成序列整数
arr = [] |
用 range()
生成 list
arr2 = list(range(1, 10, 2)) |
while
循环
sum = 0 |
高级特性
切片
'Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] > L = [ |
100)) > L = list(range( |
tuple 和 str 也可以进行切片操作,操作结果分别是 tuple 和 str。
迭代
list
迭代 value
'Michael', 'Sarah', 'Tracy'] L = [ |
同时迭代 index, value
>>> for i, value in enumerate(['A', 'B', 'C']): |
dict
迭代 key
'a': 1, 'b': 2, 'c': 3} d = { |
迭代 value
'a': 1, 'b': 2, 'c': 3} d = { |
同时迭代 key, value
'a': 1, 'b': 2, 'c': 3} d = { |
当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,我们不太关心该对象究竟是list还是其他数据类型。
那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
from collections import Iterable |
所以 str 也是可迭代的。
结尾
最初列大纲时,是没有进阶知识这一文的,因为差不多都是基础知识,但是写着写着发现 demo 太多,导致篇幅有点大,决定分出去,又不太想写个一二三,就标题党一回,叫进阶知识了,虽然不是多高深,但相对此文的基础语法,还是有一定提高的。