Python语法快速入门

/ 1

文件结构

一个 Python 源文件的结构主要分成三个部分:头部区域导入区域业务代码区域

头部区域和导入区域需要一个空行,导入区域和业务代码区域需要两个空行,这并不是语法要求,这只是强烈推荐的代码规范!

# coding:utf-8

import os

print(os.getcwd())

代码注释

Python 中有3种注释,其实也可以说是2种:

# 单行注释

"""
一对3个双引号的多行注释
"""

'''
一对3个单引号的多行注释
'''

程序入口

Python 也有类似 C 语言中的程序入口 main 主函数。

# coding:utf-8

import os

if __name__ == '__main__':
    print(os.getcwd())

执行顺序

Python 是自上而下依次解析执行的,这也就可以说明 Python 并不一定需要 main 主函数。但是建议都使用 main 主函数,并且放在程序最底部。然后在 main 主函数中调用它上面的代码,使代码结构更加清晰和利于维护。

后面笔记为了节省篇幅,不会编写完整规范的结构,只会贴出重点部分的代码!

代码缩进

Python 并没有和其他多数编程语言一样用 {} 将代码块括起来,它是通过代码缩进来区分代码块的,缩进使用一个 tab

比如下面的代码,两个 print 并不是在同一个代码块内,第二个 print 是和 if 对齐,他们是在同一个代码块。

# coding:utf-8

import os

if __name__ == '__main__':
    print(os.getcwd())
print('我回到了一级代码块')

input函数

input 函数的作用类似于 C 语言中的 scanf 函数,接收一个标准输入数据,返回为 string 类型。

result = input('请输入任意内容:')
print(result)

执行结果:

请输入任意内容:hello input
hello input

变量

命名规则

name = '小胖'
age = 20
is_sleep = True
a, b, c = 1, 2, 'c'

print(name)
print(age)
print(is_sleep)
print(c)

关键字

关键字 含义
True 布尔类型,表示真
False 布尔类型,表示假
def 函数定义
if 逻辑中的如果
elif 逻辑中的或者如果
else 逻辑中的否则
try 异常语句的开启
is 判断变量是否是某个类的实例
not 逻辑运算,非的操作
or 逻辑运算,或的操作
pass 无意义,占位字符
raise 主动跑出异常
in 判断变量是否在序列中
while while循环语句
with 简化Python语句
yield 从循环或函数依次返回数据
import 导入语句,可与from共用

数据类型

Python 会自动推导类型,定义变量的时候不一定需要使用类型函数。

数字类型

数字类型有:整型(int)浮点型(float) 类型,在 Python2 中还有 long 类型,在 Python3 被弃用。

# 整型
count_01 = int(1)
count_02 = 1

# 浮点型
pi_01 = float(3.14)
pi_02 = 3.14

字符串类型

一对单引号或一对双引号包裹起来的内容,就是字符串。在 Python 中,使用 str 来代表字符串类型。

字符串不是数字不能做减法、乘除法。字符串的拼接用 +

name = str('小胖')
info = '小胖很瘦'

用多行注释的三个引号的写法,可以定义保持原格式的字符串:

info = '''
    随便,还保持原格式
 随便来
'''
print(info)

打印结果:

    随便,还保持原格式
 随便来

布尔类型

布尔类型只有两个固定值,TrueFalse,分别表示逻辑真、逻辑假。

int 0 是 False,非 0 是 True

float 0.0 是 False,非 0.0 是 True

str ''(空字符串) 是 False,非 '' 是 True

list [](空列表)是 False,非 [] 是 True

tuple ()(空元组)是 False,非 () 是 True

dict {}(空字典)是 False,非 {} 是 True

空类型

不属于任何数据类型,就是空类型。

固定值:None,空类型属于 False 范畴。

如果不确定数据的类型,可以先定义为空类型。

列表类型

列表就是队列,他是各种数据类型的集合,是一种有序的结构,且内容可重复的集合类型。

类似很多语言中的数组集合,比如 Java 中的 ListObjective-C 中的 NSArray

在 Python 中,列表中的元素存在于中括号 [] 内,元素的类型可以不同。

names_01 = list(['小白', '小胖'])
names_02 = ['小芳', '小美']

# 列表中元素的数据类型可以不同
mix_array = ['小花', 1, 3.14, True, None]

# 判断列表中是否存在某个元素
result = 3.14 in mix_array

# max和min可以获取列表中最大和最小的元素,但数据类型需要一致
max_value = max([1, 2, 3, 4])
min_value = min([1, 2, 3, 4])

元组类型

元组与列表有些特性很像,都是一种可以存储多种数据结构的队列,并且也是有序的,且元素可以重复的集合。

在 Python 中,tuple 代表着元组这种类型,也可以用它定义一个元组。元组的元素存在于一对小括号 () 中。

元组比列表占用资源更小,列表是可变的,元组是不可变的。

元组如果只有一个元素,也必须加上 , 号,否则 Python 解析器无法识别元组。

names_01 = tuple(('小白', '小胖'))
names_02 = ('小芳', '小美')
names_03 = ('小花',) # 只有一个元素,需要加,

# 元组中元素的数据类型可以不同
mix_tuple = ('小花', 1, 3.14, True, None)

# 判断元组中是否存在某个元素
result = 3.14 in mix_tuple

# max和min可以获取元组中最大和最小的元素,但数据类型需要一致
max_value = max((1, 2, 3, 4))
min_value = min((1, 2, 3, 4))

字典类型

Python 中用 dict 来代表字典,并且可以创建一个字典。字典的元素(键值对)存在一对大括号 {} 中。

key 支持字符串、数字和元组类型,但不支持列表。在一个字典中 key 是唯一的。

value 支持 Python 的所有数据类型。

Python3.7 以前,字典是无序的。

person = {'name': '小花', 'age': 99}
test1 = {1: 'one', 2: 'two'}
test2 = {(1, 2, 3): [1, 2, 3], (4, 5, 6): [4, 5, 6]}

# 字典中key可以是不同数据类型
mix_dict = {1: '1', '1': 1}

# 判断字典中是否存在某个key
result = 1 in mix_dict

# max和min可以获取字典中最大和最小的key,但key的数据类型需要一致
max_value = max({1: '1', 2: '2'})
min_value = min({1: '1', 2: '2'})

常用内置函数

print:打印数据,输出到控制台。

type:获取数据类型,类似 C 语言中的 typeof

id:获取变量的内存地址,类似 C 语言中的 &

len:返回字符串的长度,类似 C 语言中的 strlen

max:返回数据中最大的成员。如果是字符串,则中文符号 > 字母 > 数字 > 英文符号。如果是中文,按照拼音首字母来比较。

min:返回数据中最小的成员。比较规则和 max 一致。

dir:返回指定对象的所有方法列表。

in运算符

in:成员运算符用来判断数据是否属于某个数据。

info = 'python是一个好东西'
result = '一个' in info
print(result)

result = '好' not in info
print(result)

打印结果:

True
False

比较运算符

运算符 描述 举例
== 是否等于,不是比较内存地址 a == b
!= 是否不等于 a != b
> 是否大于 a > b
< 是否小于 a < b
>= 是否大于等于 a >= b
<= 是否小于等于 a <= b
<> 是否不等于 a <> b
is 两个对象存储单元(内存地址)是否相同 a is b
is not 两个对象存储单元(内存地址)是否不同 a is not b

对象

Python 中一切都是对象,每个对象都有各自的属性和方法。

字符串常用方法

capitalize:首字母大写,其他字母如果有大写会转换为小写。

name = 'xiaoFang'
new_name = name.capitalize()
# Xiaofang

casefoldlower:都是将字符串中所有字母转为小写。

casefold 是在 Python3.3 引入的,并且支持更多小语种转小写。而 lower 则在很早的版本都可以使用,所以我们平时基本都是使用 lower即可。

name = 'xiaoFang'
new_name = name.casefold()
# xiaofang
new_name = name.lower()
# xiaofang

upper:将字符串中所有字母转为大写。

name = 'xiaoFang'
new_name = name.upper()
# XIAOFANG

swapcase:将字符串中的所有字母大小写反转,也就是是大写的字母会被转为小写,是小写的字母就转为大写。

name = 'xiaoFang'
new_name = name.swapcase()
# XIAOfANG

zfill:为字符串定义长度,如果长度不足则在字符串前填充0。

name = 'xiaoFang'
new_name = name.zfill(10)
# 00xiaoFang

new_name = name.zfill(5) # 如果定义的长度小于当前字符串的长度,则不发生变化
# xiaoFang

count:获取当前字符串中某个成员(元素)的个数,如果不存在则返回0。

注意 count 不是用来获取字符串的长度!如果想要获取字符串的长度,可以使用 len(string) 来获取。

name = 'xiaoFang'
a_count = name.count('a')
# 2

startswith:判断字符串是否以某子字符串开始。

name = 'xiaoFang'
result = name.startswith('x')
# True

endswith:判断字符串是否以某子字符串结束。

name = 'xiaoFang'
result = name.endswith('g')
# True

find:查询某子字符串的位置,返回一个整数,不存在则返回-1。字符串位置是从左向右,以0开始的。

name = 'xiaoFang'
index = name.find('A')
# -1

index:查询某子字符串的位置,返回一个整数,不存在则报错。

name = 'xiaoFang'
index = name.index('A')
# Traceback (most recent call last):
#   File "/Users/feng/Code/PyCharm/demo1/main.py", line 6, in <module>
#     index = name.index('A')
# ValueError: substring not found

strip:去掉字符串左右两边的指定子字符串,不传参默认去掉空格。

name = 'xiaoFang'
result = name.strip('g')
# xiaoFan

lstrip:仅去掉字符串左边的指定子字符串,不传参默认去掉空格。

name = 'xiaoFang'
result = name.lstrip('x')
# iaoFang

rstrip:仅去掉字符串右边的指定子字符串,不传参默认去掉空格。

name = 'xiaoFang'
result = name.rstrip('g')
# xiaoFan

replace:替换字符串中某些子字符串为新的子字符串,并且能指定替换的数量。

name = 'xiaoFang'
result = name.replace('a', '', 1)
# xioFang

isspace:判断字符串是否只由空格组成。

name = 'xiaoFang'
result = name.isspace()
# False

name = ' '
result = name.isspace()
# True

istitle:判断字符串是否是一个标题类型,也就是字符串如果由多个单词组成,并且每个单词只有首字母是大写。只能用于英文。

name = 'xiaoFang'
result = name.istitle()
# False

name = 'XiaoFang'
result = name.istitle()
# False

name = 'Xiaofang'
result = name.istitle()
# True

isupper:判断字符串是否是都是大写。

name = 'XIAOFANG'
result = name.isupper()
# True

islower:判断字符串是否是都是小写。

name = 'xiaofang'
result = name.islower()
# True

join:将序列中的元素以指定的字符连接生成一个新的字符串。

s1 = '-'
seq = ('h', 'e', 'l', 'l', 'o')
result = s1.join(seq)
# h-e-l-l-o

s2 = ''
seq = ['h', 'e', 'l', 'l', 'o']
result = s2.join(seq)
# hello

split:将字符串以指定分隔符拆分成列表。

name = 'xiaoFang xiaoMing'
result = name.split()
# ['xiaoFang', 'xiaoMing']

字符串编码格式

gbk:中文编码。

ascii:英文编码。

utf-8:国际通用的编码格式。

在 Python 源文件头部添加 #coding: 编码格式 即可。

字符串格式化

符号 说明
%s 格式化字符串,通用类型
%d 格式化整数
%f 格式化浮点型
%u 格式化无符号整型
%c 格式化字符
%o 格式化无符号8进制数
%x 格式化无符号16进制数
%e 科学记数法格式化浮点型
name = '小芳'
age = 12
height = 1.88

# 利用print函数格式化输出
print('name=%s' % name)
print('age=%d height=%.2f' % (age, height))
# name=小芳
# age=12 height=1.88

# 利用format函数格式化,这种方式支持的格式化符号比较少
print('name={:s}'.format(name))
print('age={:d} height{:.2f}'.format(age, height))
# name=小芳
# age=12 height=1.88

转义字符

字符要转成其他含义的功能,所以我们叫它转义字符。

语法格式:\+字符

符号 说明
\n 换行,一般用于末尾,strip对其也有效
\t 横向制表符(可以认为是一个间隔符)
\v 纵向制表符(会有一个男性符号)
\a 响铃
\b 退格符,将光标前移,覆盖(删除前一个)
\r 回车
\f 翻页(会有一个女性符号)
\' 转义字符串中的单引号
\" 转义字符串中的双引号
\ 转义斜杠

列表与元组常用方法

列表和元组绝大部分内置函数都是一样的。

len:计算除数字类型外的数据长度,比如列表和元组的元素个数。

names = ['xiaofang', 'xiaohua']
print(len(names))
# 2

names = ('xiaofang', 'xiaohua')
print(len(names))
# 2

in:判断某个成员(元素)是否在该数据结构中。

names = ['xiaofang', 'xiaohua']
print(bool('xiaofang' in names))
# True

names = ('xiaofang', 'xiaohua')
print(bool('xiaohua' in names))
# True

not in:判断某个成员(元素)是否不在该数据结构中。

names = ['xiaofang', 'xiaohua']
print(bool('xiaofang' not in names))
# False

names = ('xiaofang', 'xiaohua')
print(bool('xiaohua' not in names))
# False

列表/元组之间的累加与乘法:

names = ['xiaofang', 'xiaohua']
new_names = names + names
print(new_names)
# ['xiaofang', 'xiaohua', 'xiaofang', 'xiaohua']
new_names = names * 2
print(new_names)
# ['xiaofang', 'xiaohua', 'xiaofang', 'xiaohua']

names = ('xiaofang', 'xiaohua')
new_names = names + names
print(new_names)
# ('xiaofang', 'xiaohua', 'xiaofang', 'xiaohua')
new_names = names * 2
print(new_names)
# ('xiaofang', 'xiaohua', 'xiaofang', 'xiaohua')

insert:将一个元素添加到列表指定位置。

names = ['xiaofang', 'xiaohua']
names.insert(0, 'feifei')
# ['feifei', 'xiaofang', 'xiaohua']

append:将一个元素添加到列表结尾。

names = ['xiaofang', 'xiaohua']
names.append('feifei')
# ['xiaofang', 'xiaohua', 'feifei']

count:返回当前列表中的某个成员的个数,不存在则返回0。

fruits = ['苹果', '梨子', '苹果']
print(fruits.count('苹果'))
# 2

remove:删除列表中指定元素,只能删除第一个查找到的元素。

fruits = ['苹果', '梨子', '苹果']
fruits.remove('苹果')
print(fruits)
# ['梨子', '苹果']

del:将变量完全删除,如果后续还继续使用这个变量则会报错。

fruits = ['苹果', '梨子', '苹果']
del fruits

reverse:将当前列表的元素顺序反转。

fruits = ['梨子', '苹果']
fruits.reverse()
# ['苹果', '梨子']

sort:对当前列表按照一定规则进行排序,元素类型要一致,否则报错。

books = ['python', 'django', 'web']

# 降序
books.sort(reverse=True)
print(books)
# ['web', 'python', 'django']

# 升序(默认)
books.sort(reverse=False)
print(books)
# ['django', 'python', 'web']

clear:将当前列表中的数据清空。

books = ['python', 'django', 'web']
books.clear()
# []

copy:将当前列表中的元素复制到一个新的列表。修改新的列表中的元素,不会影响旧的列表,属于深拷贝。

books = ['python', 'django', 'web']
new_books = books.copy()
print('0x%x' % id(books))
print('0x%x' % id(new_books))
# 0x1029b4b00
# 0x1029b4bc0

extend:将其他列表或元组中的元素倒入到当前列表中。

books = ['python', 'django', 'web']
new_books = ['iOS', 'Android']
books.extend(new_books)
# ['python', 'django', 'web', 'iOS', 'Android']

索引与切片

字符串、列表、元组都有索引,起始从0开始,最大索引等于长度减1。

books = ['python', 'django', 'web']
print(books[0])
# python

del books[0]
print(books)
# ['django', 'web']

索引用来对单个元素进行访问,切片则对一定范围内的元素进行访问。切片类似 Swift 中的区间运算符。

切片通过冒号在中括号内把相隔的两个索引查找出来:[3: 8],切片规则:左含右不含。

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(numbers[3: 8])
# [4, 5, 6, 7, 8]

print(numbers[:])
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

print(numbers[0:])
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

print(numbers[0: -1])
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

print(numbers[:: -1])
# [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

print(numbers[-3: -1])
# [8, 9]

print(numbers[0: 8: 2])
# [1, 3, 5, 7]

print(numbers[0: 0])
# []

字典常用方法

字典可以通过 key 来修改和增加元素。

user = {'username': 'dagou', 'age': 12}
user['top'] = 177
print(user)
# {'username': 'dagou', 'age': 12, 'top': 177}

user['username'] = 'gou'
print(user)
# {'username': 'gou', 'age': 12, 'top': 177}

update:添加新的字典,如新字典中有和原字典相同的 key,则该 keyvalue 会被新的字典的 value 覆盖。

user = {'username': 'dagou', 'age': 12}
user.update({'height': 1.9})
# {'username': 'dagou', 'age': 12, 'height': 1.9}

setdefault:获取某个 keyvalue,如 key 不存在于字典中,将会添加 key 并将 value 设为默认值。

default_dict = {}
value = default_dict.setdefault('name', '小芳')
# 小芳

default_dict = {'name': '小花'}
value = default_dict.setdefault('name', '小芳')
# 小花

keys:获取字典所有的 key 的伪列表。

values:获取字典所有的 value 的伪列表。

my_dict = {'name': '小芳', 'age': 12}
keys = my_dict.keys()
values = my_dict.values()
print(keys)
print(values)
print(list(keys))
print(list(values))
# dict_keys(['name', 'age'])
# dict_values(['小芳', 12])
# ['name', 'age']
# ['小芳', 12]

通过 [] 可以根据字典的 key 获取或修改 value 的值。如果 key 不存在,获取则报错。

通过 get 内置函数可以根据字典的 key 获取 value 的值,如果 key 不存在,返回默认值。所以在开发中,优先使用 get 函数来获取数据。

copy:字典深拷贝函数,返回的字典数据相同,地址不同。所以修改新的字典中的数据不会影响旧的字典。

old_dict = {'name': '小芳', 'age': 12}
new_dict = old_dict.copy()
print(old_dict == new_dict)
print(id(old_dict) == id(new_dict))
# True
# False

innot in:判断字典中的 key 是否存在或不存在。

通过 get 函数也可以判断字典中的 key 是否存在。

my_dict = {'name': '小芳', 'age': 12}
print('name' in my_dict)
print('name' not in my_dict)
print(bool(my_dict.get('name')))
# True
# False
# True

popitem:删除当前字典末尾一组键值对并将其返回,返回数据类型为元祖。

my_dict = {'name': '小芳', 'age': 12}
print(my_dict.popitem())
print(my_dict)
# ('age', 12)
# {'name': '小芳'}

集合

set 集合,元素无序且不能重复。

集合无法通过索引获取元素,也无获取元素的任何方法。只是用来处理列表或元祖的一种临时类型,他不适合存储与传输。

a_set = set(['小芳', '小花'])
b_set = {'小芳', '小花'}

集合常用方法

add:添加元素到集合,如果已存在则不执行。

a_set = set()
a_set.add('小芳')
print(a_set)
# {'小芳'}

update:加入一个新的集合(或列表、元祖、字符串),如新集合的元素已存在则无视。

a_set = set()
a_set.update('小米')
a_set.update(['小芳', '小明'])
print(a_set)
# {'米', '小明', '小', '小芳'}

remove:将集合中的某个元素删除,如元素不存在将会报错。

a_set = set('小蜜蜂')
print(a_set)
a_set.remove('小')
print(a_set)

# {'蜜', '蜂', '小'}
# {'蜜', '蜂'}

clear:清空当前集合中的所有元素。

a_set = set('小蜜蜂')
a_set.clear()
print(a_set)
# set()

del:删除集合对象自身,无法删除集合中的元素,因为集合中的元素无索引。

intersection:返回两个或更多集合的交集,也就是每个集合中都存在的元素。

a_set = {'小米', '小兵', '小芳'}
b_set = {'小芳', '小花', '小王'}
print(a_set.intersection(b_set))
# {'小芳'}

union:返回两个或更多集合的并集,也就是包含了所有集合的元素,重复的元素只会出现一次。

a_set = {'小米', '小兵', '小芳'}
b_set = {'小芳', '小花', '小王'}
print(a_set.union(b_set))
# {'小王', '小兵', '小花', '小米', '小芳'}

isdisjoint:判断两个集合是否不包含相同的元素,如果不包含相同元素则返回 True,否则返回 False

a_set = {'小米', '小兵', '小芳'}
b_set = {'小芳', '小花', '小王'}
print(a_set.isdisjoint(b_set))
# False

数据类型转换

字符串与数字

字符串转为数字,需要字符串中所有字符都是数字才能转换,空格除外。

new_str = str(123456)
print(new_str)
new_str = str(3.14)
print(new_str)
new_int = int(' 12')
print(new_int)
new_float = float(' 1.2')
print(new_float)
# 123456
# 3.14
# 12
# 1.2

字符串与比特类型

bytes:比特类型,二进制的数据流,是一种特殊的字符串。

bt = b'my name is xiaofang'
print(type(bt))
# <class 'bytes'>

bytes 支持很多字符串的函数,只不过参数如果是字符串则需要传递比特类型。

bt = b'my name is xiaofang'
print(bt.capitalize())
print(bt.replace(b'my', b'your'))
print(bt[0])
print(bt[0:3])
print(bt.find(b'name'))
# b'My name is xiaofang'
# b'your name is xiaofang'
# 109
# b'my '
# 3

encode:将字符串转成比特(bytes)类型。

decode:将字比特(bytes)类型转成字符串。

str_data = 'my name is xiaofang 中文'
byte_data = str_data.encode('utf-8')
print(byte_data)
# b'my name is xiaofang \xe4\xb8\xad\xe6\x96\x87'

str_data = byte_data.decode('utf-8')
print(str_data)
# my name is xiaofang 中文

逻辑语句

对于一件事情的正确与否(真假的判断),判断结果为布尔类型。

if:如果。

elif:否则如果。

else:否则。

and:并且

or:或则。

number = 5
if number > 10:
    print('大于10')
elif 5 < number < 8:
    print('大于5小于8')
elif number == 5:
    print('等于5')
else:
    print('小于5')
# 等于5

循环语句

for in:将列表、元祖、字符串、字典中的每个元素按照顺序进行遍历。

for item in '字符串':
    print(item, end=',')
# 字,符,串,

while:根据条件执行循环体,可以无限循环。

count = 9
while count >= 0:
    print(count, end=',')
    count -= 1
# 9,8,7,6,5,4,3,2,1,0,

continue:跳过当前循环,继续下一次循环。

break:直接结束当前循环。

count = 9
while count >= 0:
    if count == 5:
        continue
    elif count == 2:
        break
    print(count, end=',')
    count -= 1
# 9,8,7,6,

range:返回一个可迭代对象,参数依次为开始(包括,默认0)、结束(不包括)、步长(默认1)。

for item in range(10):
    print(item, end=',')
# 0,1,2,3,4,5,6,7,8,9,

for item in range(10, 20, 2):
    print(item, end=',')
# 10,11,12,13,14,15,16,17,18,19,

函数的定义

Python 中的函数分为内置函数和自定义函数,函数定义使用 def 关键字,使用 return 关键字返回数据。

def 函数名(参数列表...):
    函数体
    return 返回值

函数参数

Python 函数的参数从左到右依次是必传参数、默认(可选)参数、可变元组参数、可变字典参数。

可选参数就是设置了默认值的参数。

可变参数就是没有固定的参数名和数量。

def 函数名(arg1, arg2 = 默认值, *args, **kwargs):
    函数体

*args:将无参数名的值合并成元组。

**kwargs:将有参数名与默认值的赋值语句合并成字典。

def test_args(*args, **kwargs):
    print(args, type(args))
    print(kwargs, type(kwargs))
test_args(1, 2, 3, name='xiaofang', age=12)
test_args(*(1, 2, 3), **{'name': 'xiaofang', 'age': 12})
# (1, 2, 3) <class 'tuple'>
# {'name': 'xiaofang', 'age': 12} <class 'dict'>

函数参数的类型

在 Python3.7 后才可以定义函数参数的类型,并且函数也不会对参数类型进行验证。

def 函数名(arg1: str, arg2: int = 默认值, *args: int, **kwargs: str):
    函数体

全局变量与局部变量

全局变量:在 Python 脚本最上层代码块的变量。可以在函数内被读取使用,但无法修改。

局部变量:在函数体内定义的变量。

global:将全局变量可以在函数体内进行修改。

name = 'xiaofang'
def test():
    global name
    name = 'xiaoming'

递归函数

在函数内,通过返回值,直接执行自身函数。

def 函数名1(arg1):
    return 函数名1(arg1)

lambda匿名函数

f = lambda: 1
print(f())
# 1

f1 = lambda x=1, y=2: x + y
print(f1())
# 3

users = [{'name': 'xiaosan'}, {'name': 'xiaohua'}, {'name': 'xiaosi'}]
users.sort(key=lambda user: user['name'])
print(users)
# [{'name': 'xiaohua'}, {'name': 'xiaosan'}, {'name': 'xiaosi'}]

验证下
类变量、实例变量和局部变量。
类方法、静态方法和实例方法。

类的self

self 是类函数中的必传参数,且必须放在第一个参数位置。

self 是一个对象,他代表实例化的变量自身。

self 可以直接通过点来定义一个类变量。

self 中的变量与含有 self 参数的函数可以在类中的任何一个函数内随意调用。

非函数中定义的变量在定义的时候不用 self

class Person(object):
    name = None
    age = None

    def run(self):
        print(f'{self.name}在奔跑')

    def jump(self):
        print(f'{self.name}在跳跃')
xiaofang = Person()
xiaofang.name = '小芳'
xiaofang.run()
xiaofang.jump()
# 小芳在奔跑
# 小芳在跳跃

类的构造函数

类中的一种默认函数,用来将类实例化的同时,将参数传入类中。

def __init__(self, a, b):
    self.a = a
    self.b = b

setter/getter

使用 property 函数:

class Rect:
    def __init__(self, area):
        self.__area = area
    def get_area(self):
        return self.__area
    def set_area(self, value):
        self.__area = value
    def del_area(self):
        self.__area = 0
    area = property(get_area, set_area, del_area)
rect = Rect(30)
rect.area = 10
print(rect.area)
# 10

del rect.area
print(rect.area)
# 0

使用 @property 属性装饰器:

class Rect:
    def __init__(self, area):
        self.__area = area
    @property
    def area(self):
        return self.__area
    @area.setter
    def area(self, value):
        self.__area = value
    @area.deleter
    def area(self):
        self.__area = 0
rect = Rect(30)
rect.area = 10
print(rect.area)
# 10

del rect.area
print(rect.area)
# 0

封装

Python 类的属性和方法可以添加两个下划线 __ 来设置为私有。

但这种方式只是 Python 的一种“投机取巧”,添加了 __ 的属性和方法,其实在底层修改了名字,在名字前了 _类名 前缀。

Python 内置了很多 类似 __init__ 这样的前后都包含下划线的写法,这是由 Python 解析器调用的,我们不要用这种命名格式。

继承

Python 如果没有显式指定父类,就是默认继承 object 类。

Python 和 C++ 一样,是支持多继承的。如果多个父类中包含同名的类方法,根据子类继承父类的前后次序决定继承哪个父类的方法,即排在前面的父类中的类方法会覆盖排在后面父类中的同名类方法

class 子类(父类1, 父类2,...):
    pass

重写父类方法

class Bird:
    def isWing(self):
        print("鸟有翅膀")
    def fly(self):
        print("鸟会飞")
class Ostrich(Bird):
    def fly(self):
        print("鸵鸟不会飞")
        super().fly()
ostrich = Ostrich()
ostrich.fly()
# 鸵鸟不会飞
# 鸟会飞

Bird.fly(ostrich)
# 鸟会飞

限制动态添加实例方法

不会对其子类生效。

class 类名:
    __slots__ = ()

动态创建类

使用内置函数 type 不仅仅可以查看某个变量的类型,还可以用于动态创建一个类。

def say(self):
    print("我要学 Python!")
CLanguage = type("CLanguage", (object,), dict(say=say, name="C语言"))
clangs = CLanguage()
clangs.say()
print(clangs.name)
# 我要学 Python!
# C语言