文章目录
- 一、变量
- (一) 类型及基本使用
- (二) 高级变量的使用
- (三) 局部变量和全局变量
- 二、函数
- (一) 基本语法和注释
- (二) 函数模块
- (三) 函数的返回值和参数
- 三、语句
- (一) 判断语句
- (二) 循环语句
一、变量
理解变量“引用”的概念,Python中变量和数据是分开存储的,利用id()
函数可以查看数据在内存中的地址 。赋值语句a=1
,可理解为计算机在内存中分配了一个地址,地址中存放的值是1,变量a引用了这个地址。令b=a
,可以发现id(a)==id(b)
,这是因为变量b也引用了这个地址,如果再令b=2
,则内存中会新分配一个地址存放2,变量b再引用这个新的地址。
(一) 类型及基本使用
- 变量类型:
数字型:整型、浮点、布尔、复数
非数字型(高级变量,容器):字符串、列表、元祖、字典 - 使用
type()
函数可以查看变量的类型 - 直接赋值,Python是弱类型语言,会自动定义变量类型,无需声明
- 数字型变量之间可以直接计算
- 使用
input()
接收用户输入,接收的内容为字符串类型,需要其他类型则需要转换,如int()
、float()
,为节省内存优化代码,建议使用height = float(input("请输入身高:"))
的形式 print()
函数默认在输出内容结尾自动加上换行符,如果不希望自动增加换行,可以利用代码print("Hello", end="")
,如果需要其他符号作为结尾则需要给end赋值,如print("Hello", end="---")
- 格式化输出有两种方式:
① 利用格式化字符:%s %d %f %x
,字符串与变量之间用%
分隔,如:print("格式化字符串" % (变量1, 变量2...))
,其中(变量1, 变量2...)
本质上是一个元祖;
② 利用字符串对象的format方法,如:print("插入{}内容:{}".format(1,{"key":"value"}))
,format()方法中的参数可以是多个不同类型的变量 - PEP8规范建议变量命令用下划线命名法,如:
temp_variable
\t
制表符用于将输出文本垂直方向保持对齐- CPython是官方使用c语言开发的python解释器
- Python在运行时,内存首先加载解释器,然后从上至下逐行代码解释运行
- del删除变量,可以释放变量分配的内存空间
(二) 高级变量的使用
1.列表
Python语言中使用最频繁的高级变量类型,索引从0开始编号,用[]
定义,例如:
name_list = ["Jim", "Tom", "Alice"]
列表方法包括:
方法 | 作用 | 返回值 |
append(object) | 在列表末尾追加对象 | None |
extend(seq) | 在列表末尾追加序列 | None |
count(object) | 统计某个对象在列表中出现的次数 | int |
index(object) | 从列表中找出某个对象第一个匹配项的索引 | int |
pop() | 移除列表中最后一个对象,并返回该对象 | object |
reverse() | 反转列表排序 | None |
sort([reverse=False]) | 列表排序,默认升序,降序令reverse=False | None |
insert(index, obj) | 将对象插入列表索引index位置 | None |
remove(object) | 移除列表中第一个匹配的对象 | None |
只需要知道有哪些功能,无需死记硬背,在编辑器中通过提示就可以查看,比如在ipython中定义列表后,可用Tab键提示进行查看。
注意:虽然列表可以存储不同类型的数据,但是一般只存储相同类型数据,最常用迭代循环方法进行相同处理
2.元祖
与列表类似,区别在于:
- 其定义时用
()
- 在定义之后不能再修改
- 通常保存不同类型的数据
name_tuple = ("Jim", 18, 165)
元祖因为不能修改所以方法比列表少很多,只剩下count()和index(),使用方法和列表相同。
元祖和列表之间的转换:
- 如果希望元祖可以修改,转换:
num_list = list(num_tuple)
- 如果希望列表不可以修改,转换:
num_tuple = tuple(num_list)
3.字典
使用{}
,以{key:value}
方式进行定义,键key
是索引,值value
是数据,键和值之间使用:
分隔,键必须是唯一的,限定字符串、数字或元祖,值可以是任何类型,如:
name_dict = {"Jim": 18,
"Alice": 20,
"Bob": 12}
字典方法包括:
方法 | 作用 | 返回值 |
clear() | 删除字典内所有内容 | None |
copy() | 复制字典并返回该字典 | dict |
get(key) | 返回字典中键为key的值(对象) | object |
update(dict) | 把字典dict的内容更新到原字典中,既可以合并字典,又可以更新键值 | None |
keys() | 返回字典中所有键,后续可用list转换为列表 | dict_keys |
values() | 返回字典中所有值,后续可用list转换为列表 | dict_values |
pop(key) | 删除字典key对应的值,并返回该值(对象) | object |
popitem() | 删除并返回字典中最后一个键值对 | object |
字典与列表的区别主要在于:
- 列表将存储的内容用顺序索引对应起来,通过索引查找内容
- 字典存储的内容(值)用键来对应起来,把键当成索引去查找内容
为字典中键值对本质上是无序的,所以在遍历字典时,输出的内容也是无序的,遍历时for key in dict
中,key是字典的键。
更常见的应用场景是将多个键值对构成一个字典,多个字典组成一个列表,利用循环体对列表进行相同操作。
4.字符串
字符串方法非常多,按功能主要分为六种:
① 查找和替换,具体如下:
方法 | 作用 | 返回值 |
find(str) | 返回str在字符串中第一次出现的索引位置,如果不存在str则返回-1 | int |
rfind(str) | 从字符串右边开始寻找 | int |
index(str) | 与find相同,但是如果不存在str则会报错 | int |
startwith(str) | 判断是否以指定的字符串开始,是则返回True,不是则返回False | bool |
endwith(str) | 判断是否以指定的字符串结束,是则返回True,不是则返回False | bool |
replace(str, repl) | 把字符串中所有str替换成repl,并不会修改原字符串 | str |
② 拆分和连接,具体如下:
方法 | 作用 | 返回值 |
split([sep=’ '[, maxsplit]]) | 以sep为分隔符拆分string,默认为空白符,包括 | List[str] |
str.join(seq) | 以字符串str为分隔符将字符串序列seq中所有的元素(以字符串表示)合并为一个新的字符串 | str |
③大小写转换,具体如下:
方法 | 作用 | 返回值 |
lower() | 转换字符串中所有大写字母为小写 | str |
upper() | 转换字符串中所有小写字母为大写 | str |
④ 判断字符类型,具体如下:
方法 | 作用 | 返回值 |
isalnum() | 判断字符串中至少有一个字符并且所有字符都是字母或数字则返回True,否则返回False | bool |
isalpha() | 判断字符串中至少有一个字符并且所有字符都是字母则返回True,否则返回False | bool |
isdigit() | 判断字符串中至少有一个字符并且所有字符都是数字则返回True,否则返回False | bool |
isnumeric() | 判断字符串中只包含数字字符(包括罗马数字和汉字数字)则返回True,否则返回False | bool |
islower() | 判断字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写则返回True,否则返回False | bool |
isupper() | 判断字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写则返回True,否则返回False | bool |
isspace() | 判断字符串中只包含空白符,包括 | bool |
⑤ 文本对齐,具体如下:
方法 | 作用 | 返回值 |
ljust(width[, fillchar=’ ']) | 字符串左对齐,并用fillchar字符向右补齐到width宽度,fillchar默认为空格 | str |
rjust(width[, fillchar=’ ']) | 字符串右对齐,并用fillchar字符向左补齐到width宽度,fillchar默认为空格 | str |
center(width[, fillchar=’ ']) | 字符串左对齐,并用fillchar字符向两边补齐到width宽度,fillchar默认为空格 | str |
⑥ 去除空白字符,具体如下:
方法 | 作用 | 返回值 |
strip(chars) | 删除字符串两侧的指定字符串,默认为空白符,包括 | str |
lstrip(chars) | 删除字符串左侧的指定字符串,默认为空白符,包括 | str |
rstrip(chars) | 删除字符串右侧的指定字符串,默认为空白符,包括 | str |
5.容器的共同特点:
所有非数字型变量(列表、元祖、字典、字符串)都是一个序列,也可以理解为容器,容器有许多共同特点如:
- 可以用
[]
取值 - 遍历
for in
- 计算长度、最大/最小值、比较、删除
- 链接
+
和重复*
- 切片
① python内置函数:len、del、max、min
- len():统计容器中元素个数
- del():删除容器
- max():返回容器中最大值,如果是字典,只返回key的最大值
- min():返回容器中最小值,如果是字典,只返回key的最小值
② 切片支持的容器类型包括列表、元祖、字符串
通过 容器[开始索引:结束索引:步长]
- 注意序列的第一个元素索引为0
- 步长即有间隔的进行切片,逆序的步长为-1
- -index为倒序索引,最后一个元素索引为-1,如果要切到末尾,则结束索引为空即可
例如:
[0,1,2,3,4,5][1:3] -> [1,2]
[0,1,2,3,4,5][::-1] -> [5,4,3,2,1,0]
[0,1,2,3,4,5][-1:-3:-1] -> [5,4]
③ 运算符
-
in
、not in
:列表、元祖、字典、字符串 -
*
、+
、-
、>=
、==
:列表、元祖、字符串
(三) 局部变量和全局变量
1.定义
局部变量:在函数内部定义的变量
全局变量:在函数外部定义的变量
2.变量的生命周期
变量的生命周期指变量被创建到被系统回收的时间:
- 局部变量在函数执行时被创建,在函数运行结束后被系统回收
- 全局变量在解释器解析运行时就被创建,在程序运行结束后被系统回收
3.变量的作用域
作用域也叫命名空间:
- 局部变量的作用域仅为函数内部
- 全局变量(包括模块中定义的全局变量)的作用域为整个程序
4.全局变量使用规则
不推荐使用全局变量,因为全局变量可变范围太大,程序不好维护,例如如果程序员甲修改了a的值,程序员乙同时也要使用a,这时可能导致程序中的错误。
Python规定:只能在函数内部引用全局变量,但是不允许使用赋值语句修改全局变量的值,如果使用赋值语句,则只会在函数内部自动新生成一个局部变量,此变量并不是我们要修改的全局变量。
gl_num = 10
def demo1():
gl_num = 99
print("num is %d" % gl_num)
def demo2():
print("num is %d" % gl_num)
demo1()
demo2()
输出结果:
num is 99
num is 10
函数内部调用变量时,有局部变量就会输出局部变量,没有的话才会向上寻找全局变量。
如果函数内部确需要对全局变量进行修改,这时要用global
事先声明,这样函数就不会当成局部变量生成,如上述代码修改为:
gl_num = 10
def demo1():
global gl_num
gl_num = 99
print("num is %d" % gl_num)
def demo2():
print("num is %d" % gl_num)
demo1()
demo2()
输出结果:
num is 99
num is 99
5.全局变量定义习惯
(1) 定义全局变量的位置
建议将模块中的所有全局变量,定义在所有函数的上方,以便函数可以访问到变量,一般代码结构如下:
— shebang
— import modules
— global variables
— def functions
— executing code
(2) 全局变量命名的建议
建议在下方加上g_
或gl_
或global_
,加以区分,避免和普通变量混淆。
二、函数
(一) 基本语法和注释
def name(chch, times)
"""注释
:param chch asdf
:param times: qwer
"""
code
注意:
- 函数要遵循先定义、再使用的原则,Python解释器首先要知道函数的定义,然后才能执行函数
- Pycharm调试中
step into
和step over
的区别,都是单步执行,但step into
会跳进函数内部执行 - Pycharm在
view->quick document
中可以查看函数的注释说明,快捷键Ctrl+Q
,可以利用此方法查看函数的使用方法和释义 - PEP8规范建议在函数定义的上方和其他代码保持两个空行
- Pycharm中,光标放在函数位置,选择小灯泡,选择
insert document stub
,会自动生成带参数说明的标准注释
(二) 函数模块
1.定义
- 以py结尾的源码文件都是模块
- 模块中定义的全局变量和函数都是能给外界直接使用的工具
2.使用方法
module.variable
module.function
module.module
3.运行原理
- 首先处理源代码,编译生成一个二进制字节码
- 在对字节码进行处理,生成CPU能够识别的机器码
4.pyc文件
python解释器在运行时会将导入的模块源码转换为字节码,保存在__pycache__
目录下,遇到关键字import,检查源文件和字节码文件的时间戳,如果相同,则直接加载pyc字节码文件,跳过编译过程,以优化执行速度。
(三) 函数的返回值和参数
1.函数的返回值
- 函数可以通过return返回多个数据,比如元祖、字典和列表,当返回元祖时,可以将
()
去掉 - 元祖、字典和列表既可以作为一个整体返回,也可以同时给多个变量赋值
def demo():
name = "Jim"
age = 10
return name,age
aa, bb = demo()
cc = demo()
print(aa)
print(cc)
输出结果:
'Jim'
('Jim', 10)
2.函数的参数
因为Python解释器可以自动判断变量类型,因此函数无需定义返回值类型,函数的形参也无需定义类型。函数内部针对形参赋值,并不会改变实参的值,如以下语句:
gl_num = [1,3,4]
def demo(num):
num = [5,6]
return num
print(demo(gl_num))
print(gl_num)
输出结果:
[5,6]
[1,3,4]
程序运行时,首先在内存中为全局变量gl_num开辟出一个空间,执行到demo函数时num形参会指向这个空间,当重新给num赋值时,Python会新开辟一个空间,形参重新指向新的空间,成为新的引用,函数执行完num变量以及其指向的空间也随之释放。
但是如果函数传递的形参通过调用方法对自身进行修改,那么一样会影响实参,因为没有赋值语句,形参并没有指向新的引用。
gl_num = [1,3,4]
def demo(list_num):
list_num.append(5)
return list_num
print(demo(gl_num))
print(gl_num)
结果输出:
[1, 3, 4, 5]
[1, 3, 4, 5]
3.函数的缺省参数
(1) 基本使用
- 定义函数时,给某个参数指定一个默认值,具有默认值的参数即为缺省参数
- 调用参数时,如果没有传入缺省参数的值,则在函数内部使用定义函数时指定的参数默认值,从而简化函数的使用
指定函数的缺省参数,在定义函数的参数使用赋值语句即可:
def print_info(name, gender = True):
if gender == True:
print("%s is man" % name)
else:
print("%s is woman" % name)
print_info("Jim")
print_info("Aimy", False)
输出结果:
Jim is man
Aimy is woman
(2) 定义缺省参数的注意事项
- 缺省参数应该放在函数参数的最后位置
- 在调用具有多个缺省参数的函数时,指定缺省参数应该指定参数名,避免赋值顺序错乱
(3) 多值参数
有时可能需要一个函数能够处理的参数个数是不确定的,这个时候,就可以使用多值参数,Python中有两种多值参数:
- 参数名前增加
*
可以接收元祖,习惯用*args
- 参数名前加
**
可以接收字典,习惯用**kwargs
def demo(name, *age, **info):
print("name is {}".format(name))
print("args is {}".format(age))
print("kwargs is {}".format(info))
demo(1, 2, 3, 4)
demo(1, 2, 3, country="CN")
输出结果:
name is 1
args is (2, 3, 4)
kwargs is {}
name is 1
args is (2, 3)
kwargs is {'country': 'CN'}
(4) 元祖和字典的拆包
在调用带有多值参数的函数时,如果希望:
- 将一个元祖变量,直接传递给
args
- 将一个字典变量,直接传递给
kwargs
就可以使用拆包,简化参数的传递,拆包的方式是:
- 在元祖变量前,增加
*
- 在字典变量前,增减
**
def demo(*num, **person):
print(num)
print(person)
gl_num = (1,2,3)
gl_dict = {"name":"Jim", "age":18}
demo(gl_num, gl_dict)
demo(*gl_num, **gl_dict)
输出结果:
((1, 2, 3), {'name': 'Jim', 'age': 18})
{}
(1, 2, 3)
{'name': 'Jim', 'age': 18}
4.函数的递归
函数调用自身的编程技巧称为递归
(1) 递归函数的特点
- 函数内部代码是相同的,只是针对参数不同,处理的结果不同
- 当参数满足一个条件时,函数不再执行,通常被称为函数的出口,不然会出现死循环(非常重要)
def sum_number(num):
print(num)
if num == 1:
return
sum_number(num-1)
sum_number(5)
(2) 递归案例——计算数字累加
def sum_numbers(num):
if num == 1:
return 1
temp = sum_numbers(num-1)
return temp + num
递归在处理不确定的循环条件时格外有用,例如遍历整个文件目录的结构。
三、语句
(一) 判断语句
判断语句if:
if condition:
print...
else:
print...
注意:
- 缩进Tab和空格不能混用
- 如果条件很长如
if () or () or () or()
,这样代码可读性较差,可在逻辑运算外加上括号,括号内的代码可以调整格式换行,以使得代码更具有可读性
if (()
or ()
or ()
or ()):
pass
(二) 循环语句
- while语句程序计数养成习惯,从0开始
- break和continue区别,break是跳出整个循环,continue是跳出当次循环
- 循环遍历 for语句 迭代遍历,提高了列表的访问效率
for 形参变量名 in 列表:
pass
break
else:
没有通过break退出循环,循环结束后,会执行的代码
注意:
- 虽然列表也可以存储不同类型数据,单数一般存储相同类型的数据
- 可以遍历所有非数字型类型的变量:列表、元祖、字典、字符串