本文旨在更好地总结 Python 基础知识,力求简明扼要,以供实战演练时能够快速查询遗忘的知识点。
学一门语言贵在坚持用它,不用就淡忘了,而记录下一篇文章也有助于日后快速回忆。全文分为两大部分,分别是Python基础语法和面向对象。
Python 的创始人为 吉多·范罗苏姆(Guido van Rossum)。
Python 的设计目标:
Python 的设计哲学:
Python 开发者的哲学是:用一种方法,最好是只有一种方法来做一件事
Python 是完全面向对象的语言,在 Python 中一切皆对象。
可扩展性:如果需要一段关键代码运行得更快或者希望某些算法不公开,可以把这部分程序用 C
或 C++
编写,然后在 Python 程序中使用它们。
执行 Python 程序的三种方式: 解释器、交互式运行、IDE运行
Python 是一个格式非常严格的程序设计语言。
为了照顾现有的程序,官方提供了一个过渡版本 —— Python 2.7。
提示:如果开发时,无法立即使用 Python 3.0(还有极少的第三方库不支持 3.0 的语法),建议
IPython 是一个 python 的 交互式 shell,比默认的 python shell
好用得多,它支持 bash shell
命令,适合于学习/验证 Python 语法或者局部代码。
集成开发环境(IDE
,Integrated Development Environment)—— 集成了开发软件需要的所有工具,一般包括以下工具:
PyCharm 的 配置信息 是保存在用户家目录下 的 .PyCharmxxxx.x
目录下的,xxxx.x
表示当前使用的 PyCharm 的版本号
$ rm -r ~/.PyCharm2016.3
重新启动 PyCharm
执行以下终端命令,解压缩下载后的安装包
$ tar -zxvf pycharm-professional-2017.1.3.tar.gz
将解压缩后的目录移动到 /opt
目录下,可以方便其他用户使用
/opt
目录用户存放给主机额外安装的软件$ sudo mv pycharm-2017.1.3/ /opt/
切换工作目录
$ cd /opt/pycharm-2017.1.3/bin
启动 PyCharm
$ ./pycharm.sh
Create the entry for all users
快捷方式文件 /usr/share/applications/jetbrains-pycharm.desktop
在 ubuntu 中,应用程序启动的快捷方式通常都保存在 /usr/share/applications 目录下
要卸载 PyCharm 只需要做以下两步工作:
删除解压缩目录
$ sudo rm -r /opt/pycharm-2016.3.1/
删除家目录下用于保存配置信息的隐藏目录
$ rm -r ~/.PyCharm2016.3/
如果不再使用 PyCharm 还需要将 /usr/share/applications/ 下的 jetbrains-pycharm.desktop 删掉
PyCharm
中,要想让哪一个 Python
程序能够执行,必须首先通过 鼠标右键的方式执行 一下以 #
开头,#
右边的所有东西都被当做说明文字,而不是真正要执行的程序,只起到辅助说明作用
print("hello python") # 输出 `hello python`
为了保证代码的可读性,
#
后面建议先添加一个空格,然后再编写相应的说明文字;为了保证代码的可读性,注释和代码之间 至少要有 两个空格。
要在 Python 程序中使用多行注释,可以用 一对 连续的 三个 引号(单引号和双引号都可以)
"""
这是一个多行注释
在多行注释之间,可以写很多很多的内容……
"""
print("hello python")
提示:
Python
官方提供有一系列 PEP(Python Enhancement Proposals) 文档,其中第 8 篇文档专门针对 Python 的代码格式 给出了建议,也就是俗称的 PEP 8:是完成基本的算术运算使用的符号,用来处理四则运算,而“+”和“*”还可以用来处理字符串。
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 | 10 + 20 = 30 |
- | 减 | 10 - 20 = -10 |
* | 乘 | 10 * 20 = 200 |
/ | 除 | 10 / 20 = 0.5 |
// | 取整除 | 返回除法的整数部分(商) 9 // 2 输出结果 4 |
% | 取余数 | 返回除法的余数 9 % 2 = 1 |
** | 幂 | 又称次方、乘方,2 ** 3 = 8 |
<>
运算符!=
在 Python 2.x 中同样可以用来判断 不等于身份运算符比较两个对象的内存位置。常用的有两个身份运算符,如下所述:
Python成员运算符测试给定值是否为序列中的成员。有两个成员运算符,如下所述:
Python程序执行示意图
# 1. 确认解释器所在位置
$ which python
# 2. 查看 python 文件大小(只是一个软链接)
$ ls -lh /usr/bin/python
# 3. 查看具体文件大小
$ ls -lh /usr/bin/python2.7
变量名 = 值
使用交互式方式,如果要查看变量内容,直接输入变量名即可,不需要使用 print 函数 使用解释器执行,如果要输出变量的内容,必须要要使用 print 函数
int
):Python3中的所有整数都表示为长整数。因此,长整数没有单独的数字类型。float
)bool
) :真 True 非 0 数 —— 非零即真,假 False 0。complex
):复数是由x + yj表示的有序对的实数浮点数组成,其中x和y是实数,j是虚数单位。str
):加号(+)是字符串连接运算符,星号(*)是重复运算符。tuple
)dict
)提示:在 Python 2.x 中,整数 根据保存数值的长度还分为:
In [1]: type(name)
True
对应的数字是 1False
对应的数字是 0字符串变量 = input("提示信息:")
price = float(input("请输入价格:"))
语法格式如下:
print("格式化字符串" % 变量1)
print("格式化字符串" % (变量1, 变量2...))
标示符就是程序员定义的 变量名、函数名
关键字 就是在 Python 内部已经使用的标识符
In [1]: import keyword
In [2]: print(keyword.kwlist)
命名规则 可以被视为一种 惯例,并无绝对与强制 目的是为了 增加代码的识别和可读性 注意
Python
中的 标识符 是 区分大小写的
当然,还有驼峰命名法:
firstName
、lastName
。FirstName
、LastName
、CamelCase
。在 Python
中,所有 非数字型变量 都支持以下特点:
sequence
,也可以理解为 容器[]
for in
len
、最大/最小值max/min
、比较、删除del
+
和 重复 *
List
(列表) 是 Python 中使用 最频繁 的数据类型,在其他语言中通常叫做 数组,专门用于存储 一串 信息,列表用 [] 定义,数据 之间使用 , 分隔,列表的 索引 从 0 开始。索引 就是数据在 列表 中的位置编号,索引 又可以被称为 下标 注意:从列表中取值时,如果 超出索引范围,程序会报错
name_list = ["zhangsan", "lisi", "wangwu"]
列表示意图
del
关键字(delete
) 同样可以删除列表中元素del
关键字本质上是用来 将一个变量从内存中删除的del
关键字将变量从内存中删除,后续的代码就不能再使用这个变量了In [1]: l = [1,2,3,4]
In [2]: del l[1]
In [3]: l[1]
Out[3]: 3
在日常开发中,要从列表删除数据,建议 使用列表提供的方法
函数名(参数)
函数需要死记硬背
对象.方法名(参数)
在变量后面输入 .,然后选择针对这个变量要执行的操作,记忆起来比函数要简单很多
# for 循环内部使用的变量 in 列表
for name in name_list:
循环内部针对列表元素进行操作
print(name)
for-in循环流程图
info_tuple = ("zhangsan", 18, 1.75)
创建空元组:
info_tuple = ()
元组中 只包含一个元素 时,需要 在元素后面添加逗号:
info_tuple = (50, )
元组示意图
list
函数可以把元组转换成列表list(元组)
tuple
函数可以把列表转换成元组tuple(列表)
dict(字典) 是 除列表以外 Python 之中 最灵活 的数据类型。 字典同样可以用来 存储多个数据,通常用于存储 描述一个 物体 的相关信息
xiaoming = {"name": "小明",
"age": 18,
"gender": True,
"height": 1.75}
字典示意图
字典的遍历 就是 依次 从 字典 中获取所有键值对:
# for 循环内部使用的 `key 的变量` in 字典
for k in xiaoming:
print("%s: %s" % (k, xiaoming[k]))
提示:在实际开发中,由于字典中每一个键值对保存数据的类型是不同的,所以针对字典的循环遍历需求并不是很多
card_list = [{"name": "张三",
"qq": "12345",
"phone": "110"},
{"name": "李四",
"qq": "54321",
"phone": "10086"}
]
\"
或者 \'
做字符串的转义,但是在实际开发中:for
循环遍历 字符串中每一个字符大多数编程语言都是用 “ 来定义字符串
string = "Hello Python"
for c in string:
print(c)
字符串示意图
提示:在 python 中对字符串操作,内置提供的方法足够多,使得在开发时,能够针对字符串进行更加灵活的操作!应对更多的开发需求!
字符串索引示意图
字符串[开始索引:结束索引:步长]
注意:
起始
位开始,到 结束位
的前一位 结束(不包含结束位本身)num_str = "0123456789"
# 1. 截取从 2 ~ 5 位置 的字符串
print(num_str[2:6])
# 2. 截取从 2 ~ `末尾` 的字符串
print(num_str[2:])
# 3. 截取从 `开始` ~ 5 位置 的字符串
print(num_str[:6])
# 4. 截取完整的字符串
print(num_str[:])
# 5. 从开始位置,每隔一个字符截取字符串
print(num_str[::2])
# 6. 从索引 1 开始,每隔一个取一个
print(num_str[1::2])
# 倒序切片
# -1 表示倒数第一个字符
print(num_str[-1])
# 7. 截取从 2 ~ `末尾 - 1` 的字符串
print(num_str[2:-1])
# 8. 截取字符串末尾两个字符
print(num_str[-2:])
# 9. 字符串的逆序(面试题)
print(num_str[::-1])
Python 包含了以下内置函数:
注意:字符串 比较符合以下规则:“0” < “A” < “a”。
描述 Python 表达式 结果 支持的数据类型 切片 “0123456789”[::-2] “97531” 字符串、列表、元组
注意
在 Python 中完整的 for 循环 的语法如下:
for 变量 in 集合:
循环体代码
else:
没有通过 break 退出循环,循环结束后,会执行的代码
应用场景:
在 Python 中:变量 和 数据 是分开存储的,数据 保存在内存中的一个位置,变量 中保存着数据在内存中的地址,就叫做 引用,使用 id() 函数可以查看变量中保存数据所在的 内存地址。
注意:如果变量已经被定义,当给一个变量赋值的时候,本质上是 修改了数据的引用
在 Python 中,变量的名字类似于 便签纸 贴在 数据 上:
在 Python 中,函数的 实参/返回值 都是是靠 引用 来传递来的
def test(num):
print("-" * 50)
print("%d 在函数内的内存地址是 %x" % (num, id(num)))
result = 100
print("返回值 %d 在内存中的地址是 %x" % (result, id(result)))
print("-" * 50)
return result
a = 10
print("调用函数前 内存地址是 %x" % id(a))
r = test(a)
print("调用函数后 实参内存地址是 %x" % id(a))
print("调用函数后 返回值内存地址是 %x" % id(r))
结果
注意:字典的 key 只能使用不可变类型的数据
注意
可变类型的数据变化,是通过 方法 来实现的 如果给一个可变类型的变量,赋值了一个新的数据,引用会修改 变量 不再 对之前的数据引用 变量 改为 对新赋值的数据引用
哈希
是一种 算法,其作用就是提取数据的 特征码(指纹),相同的内容 得到 相同的结果,不同的内容 得到 不同的结果。提示:在其他的开发语言中,大多 不推荐使用全局变量 —— 可变范围太大,导致程序不好维护!
注意:函数执行时,需要处理变量时 会:
注意:函数不能直接修改全局变量的引用,如果要修改,必须要用global声明该变量是全局变量。
num = 10
def demo1():
print("demo1" + "-" * 50)
# global 关键字,告诉 Python 解释器 num 是一个全局变量
global num
# 只是定义了一个局部变量,不会修改到全局变量,只是变量名相同而已
num = 100
print(num)
def demo2():
print("demo2" + "-" * 50)
print(num)
demo1()
demo2()
print("over")
注意:为了避免局部变量和全局变量出现混淆,在定义全局变量时,有些公司会有一些开发要求,例如:全局变量名前应该增加 g 或者 gl 的前缀。
1、if 判断语句基本语法:
if 要判断的条件:
条件成立时,要做的事情
……
注意:代码的缩进为一个 tab 键,或者 4 个空格 —— 建议使用空格
2、如果需要在 不满足条件的时候,做某些事情,该如何做呢?
if 要判断的条件:
条件成立时,要做的事情
……
else:
条件不成立时,要做的事情
……
条件1 and 条件2 :两个条件同时满足,返回 True
条件1 or 条件2:两个条件只要有一个满足,返回 True
not 条件:非,不是
3、如果希望 再增加一些条件,条件不同,需要执行的代码也不同 时,就可以使用 elif :
if 条件1:
条件1满足执行的代码
……
elif 条件2:
条件2满足时,执行的代码
……
elif 条件3:
条件3满足时,执行的代码
……
else:
以上条件都不满足时,执行的代码
……
注意
4、在开发中,使用 if 进行条件判断,如果希望 在条件成立的执行语句中 再 增加条件判断,就可以使用 if 的嵌套:
if 条件 1:
条件 1 满足执行的代码
……
if 条件 1 基础上的条件 2:
条件 2 满足时,执行的代码
……
# 条件 2 不满足的处理
else:
条件 2 不满足时,执行的代码
# 条件 1 不满足的处理
else:
条件1 不满足时,执行的代码
……
Python
中,要使用随机数,首先需要导入 随机数 的 模块 —— “工具包”
import random
random.randint(a, b)
,返回 [a, b]
之间的整数,包含 a
和 b
例如:
random.randint(12, 20) # 生成的随机数n: 12 <= n <= 20
random.randint(20, 20) # 结果永远是 20
random.randint(20, 10) # 该语句是错误的,下限必须小于上限
# 导入随机工具包
# 注意:在导入工具包的时候,应该将导入的语句,放在文件的顶部
# 因为,这样可以方便下方的代码,在任何需要的时候,使用工具包中的工具
import random
# 从控制台输入要出的拳 —— 石头(1)/剪刀(2)/布(3)
player = int(input("请输入您要出的拳 石头(1)/剪刀(2)/布(3):"))
# 电脑 随机 出拳 —— 先假定电脑只会出石头,完成整体代码功能
computer = random.randint(1, 3)
print("玩家选择的拳头是 %d - 电脑出的拳是 %d" % (player, computer))
# 比较胜负
# 1 石头 胜 剪刀
# 2 剪刀 胜 布
# 3 布 胜 石头
# if (()
# or ()
# or ()):
if ((player == 1 and computer == 2)
or (player == 2 and computer == 3)
or (player == 3 and computer == 1)):
print("欧耶,电脑弱爆了!")
# 平局
elif player == computer:
print("真是心有灵犀啊,再来一盘")
# 其他的情况就是电脑获胜
else:
print("不服气,我们决战到天明!")
在程序开发中,一共有三种流程方式:
顺序 —— 从上向下,顺序执行代码 分支 —— 根据条件判断,决定执行代码的 分支 循环 —— 让 特定代码 重复 执行 程序执行的三大流程
while 语句基本语法:
初始条件设置 —— 通常是重复执行的 计数器
while 条件(判断 计数器 是否达到 目标次数):
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
...(省略)...
处理条件(计数器 + 1)
由于程序员的原因,忘记 在循环内部 修改循环的判断条件,导致循环持续执行,程序将陷入死循环而无法终止!
计数器 +1 :可以通过赋值运算符简化代码的编写。 常见的计数方法有两种,可以分别称为:
因此,大家在编写程序时,应该尽量养成习惯:除非需求的特殊要求,否则 循环 的计数都从 0 开始
break 和 continue 是专门在循环中使用的关键字
while 条件 1:
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
...(省略)...
while 条件 2:
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
...(省略)...
处理条件 2
处理条件 1
示例:
"""
打印 9 行小星星:
*
**
***
****
*****
******
*******
********
*********
"""
# 定义起始行
row = 1
# 最大打印 9 行
while row <= 9:
# 定义起始列
col = 1
# 最大打印 row 列
while col <= row:
# end = "",表示输出结束后,不换行
# "\t" 可以在控制台输出一个制表符,协助在输出文本时对齐
print("%d * %d = %d" % (col, row, row * col), end="\t")
# 列数 + 1
col += 1
# 一行打印完成的换行
print("")
# 行数 + 1
row += 1
\t
在控制台输出一个 制表符,协助在输出文本时 垂直方向 保持对齐\n
在控制台输出一个 换行符制表符 的功能是在不使用表格的情况下在 垂直方向 按列对齐文本
转义字符 | 描述 |
---|---|
\ | 反斜杠符号 |
\’ | 单引号 |
\” | 双引号 |
\n | 换行 |
\t | 横向制表符 |
\r | 回车 |
所谓函数
,就是把 具有独立功能的代码块 组织为一个小模块,在需要的时候 调用。在开发程序时,使用函数可以提高编写的效率以及代码的 重用,函数的使用包含两个步骤:
定义函数:
def 函数名():
函数封装的代码
……
函数调用:通过 函数名() 即可完成对函数的调用。
PyCharm 的调试工具:
注意:因为 函数体相对比较独立,函数定义的上方,应该和其他代码(包括注释)保留 两个空行
def sum_2_num(num1, num2):
result = num1 + num2
print("%d + %d = %d" % (num1, num2, result))
sum_2_num(50, 20)
问题 1:在函数内部,针对参数使用 赋值语句,会不会影响调用函数时传递的 实参变量?—— 不会!
问题 2:如果传递的参数是 可变类型,在函数内部,使用 方法 修改了数据的内容,同样会影响到外部的数据,例如列表变量调用 += 本质上是在执行列表变量的 extend 方法。
定义函数时,可以给某个参数指定一个默认值,具有默认值的参数就叫做缺省参数,* 调用函数时,如果没有传入缺省参数的值,则在函数内部使用定义函数时指定的 参数默认值,将常见的值设置为参数的缺省值,从而 简化函数的调用。例如:对列表排序的方法:
gl_num_list = [6, 3, 9]
# 默认就是升序排序,因为这种应用需求更多
gl_num_list.sort()
print(gl_num_list)
# 只有当需要降序排序时,才需要传递 `reverse` 参数
gl_num_list.sort(reverse=True)
print(gl_num_list)
在参数后使用赋值语句,可以指定参数的缺省值
def print_info(name, gender=True):
gender_text = "男生"
if not gender:
gender_text = "女生"
print("%s 是 %s" % (name, gender_text))
提示
注意
有时可能需要 一个函数 能够处理的参数 个数 是不确定的,这个时候,就可以使用 多值参数。
*
可以接收 元组**
可以接收 字典def demo(num, *args, **kwargs):
print(num)
print(args)
print(kwargs)
demo(1, 2, 3, 4, 5, name="小明", age=18, gender=True)
print("-"*20)
demo(1,(2,3,4,5),{"name":"小明", "age":18, "gender":True})
print("-"*20)
demo(1,(2,3,4,5), name="小明", age=18, gender=True)
结果
def demo(*args, **kwargs):
print(args)
print(kwargs)
# 需要将一个元组变量/字典变量传递给函数对应的参数
gl_nums = (1, 2, 3)
gl_xiaoming = {"name": "小明", "age": 18}
# 会把 num_tuple 和 xiaoming 作为元组传递个 args
# demo(gl_nums, gl_xiaoming)
demo(*gl_nums, **gl_xiaoming)
注意:return 表示返回,后续的代码都不会被执行
def sum_2_num(num1, num2):
"""对两个数字的求和"""
return num1 + num2
# 调用函数,并使用 result 变量接收计算结果
result = sum_2_num(10, 20)
print("计算结果是 %d" % result)
函数参数和返回值
技巧
# Python 专有,利用元组交换两个变量的值
a, b = b, a
def test1():
print("*" * 50)
print("test 1")
print("*" * 50)
def test2():
print("-" * 50)
print("test 2")
test1()
print("-" * 50)
test2()
提示:工作中针对需求的变化,应该冷静思考,不要轻易修改之前已经完成的,能够正常执行的函数!
函数调用自身的 编程技巧 称为递归
特点:一个函数 内部 调用自己
代码特点:
需求:
def sum_numbers(num):
if num == 1:
return 1
# 假设 sum_numbers 能够完成 num - 1 的累加
temp = sum_numbers(num - 1)
# 函数内部的核心算法就是 两个数字的相加
return num + temp
print(sum_numbers(2))
模块是 Python 程序架构的一个核心概念
模块 就好比是 工具包,要想使用这个工具包中的工具,就需要 导入 import 这个模块, 每一个以扩展名 py 结尾的 Python 源代码文件都是一个 模块,在模块中定义的 全局变量 、 函数 都是模块能够提供给外界直接使用的工具。
模块可以让 曾经编写过的代码 方便的被 复用! 模块名也是一个标识符,如果在给 Python 文件起名时,以数字开头 是无法在 PyCharm 中通过导入这个模块的。
C 是 compiled 编译过 的意思。
pyc
文件是由 Python 解释器将 模块的源码 转换为 字节码。Python 这样保存 字节码 是作为一种启动 速度的优化。