学习python基础函数编程部分梳理

第九节/第十节

三元运算【三目运算】

  • 语法:
    • "v = a if a >b else b" #自我总结:当条件满足时返回a,条件不满足时返回b

函数

1.函数基础

1.1函数基础结构

def 函数名(参数):
    #函数内容
    pass
函数名(参数) # 执行函数 

1.2返回值

  • return值,函数默认return None
def func():
    reuturn 1,3,"abc" #这种情况会自动转换为元组返回

1.3函数参数

  • 函数的参数传递是什么?【内存地址=引用】
  • 任意个数
  • 任意类型
  • 位置传参
def func(name,age,gender):
    pass
func("伊万科夫",25,"人妖")
  • 关键字传参
    & 关键字与位置混合传参的情况,位置参数一定在前,关键字参数在后
  • 参数默认值【定义】
    & 如果给默认值为可变类型---》坑
#该部分代码解释了为什么默认值慎用可变类型
def func(data,value=[]):
    value.append(data)
    return value
v1=func(1) #[1,]
v2=func(1,[11,22,33]) # [11,22,33,1]
v3=func(2) # [1,2]
print(v1) #[1,2]
def func(name,age,gender='男'):
    pass
func("伊万科夫",25,gender="人妖")
func("伊万科夫",gender="人妖",25)  # 错误方式
func("伊万科夫",25)     # gender不传的情况下使用默认值 “男”
  • 万能参数
    • *args 接收任意个数的位置参数
      & 可以接收任意个数的参数,并且将所有参数转换成一个元组

      def func(*args): # 将所有参数打包成元组传递
          print(args)
      v1 = func((11,22,33,44,55)) #将参数元祖作为整个元组的第一个参数
      print(v1) # ((11,22,33,44,55),)
      v2 = func(*(11,22,33,44,55))# 将元组元素打散再打包成元组传递
      print(v1) # (11,22,33,44,55)
      #**********************************************************
      def func(*args,**kwargs):
          print(args)
          print(kwargs)
      func(*(11,"aaa"),444,"abc",name="沙鳄鱼",age='30')
      """
      (11, 'aaa', 444, 'abc')
      {'name': '沙鳄鱼', 'age': '30'}
      """
      
    • **kwargs 接收任意个数的关键字参数
      & 接收关键字参数,按键值转换成字典

      def func(**kwargs):
          print(kwargs)
      func(k1="v1",k2="v2")  #转换字典{"k1":"v1","k2":"v2"}
      func(**{"k1":"v1","k2":"v2"})  #直接传递字典{"k1":"v1","k2":"v2"}
      #**********************************************************
      def func(*args,**kwargs):
          print(args)
          print(kwargs)
      func((11,"aaa"),444,"abc",name="沙鳄鱼",age='30')
      """
      ((11, 'aaa'), 444, 'abc')
      {'name': '沙鳄鱼', 'age': '30'}
      """
      

1.4 函数作用域

  • 全局作用域
  • 局部作用域
  • 总结:
    • 一个函数一个作用域
    • 作用域中查找数据规则:现在自己的作用域内部查找,找不到在沿父级查找
    • 子作用域只能使用父级变量的值,不能重新给其父级的变量赋值 【给变量重新赋值相当于在子作用域给自己定义了新的变量】
    • 对于可变类型变量,子作用域可对其进行修改
    • 如果需要给全局中的变量赋值,需要使用global关键字找到全局变量
name = 'enki'
def func():
    global name # global 关键字 只找全局的变量 【global关键字只查找全局中的变量】
    name = 'alex' 
- 查找父级【上一级】的变量
# 使用关键noglobal关键字
  • 变量命名规范
    • 全局变量全大写
    • 局部变量全小写

第11节/第12节

1.函数的小高级

1.1 函数的赋值

  • 函数名赋值
def func():
    pass
v1 = func 
v1()
  • 函数可以放到list,dict,set,tuple,也可以作为字典的键和值
  • 函数名可以当做变量名使用
  • 函数可以当做参数传递
def func(arg):
    print(arg)
 def show():
    return 9
func(show)
def func(arg):
    arg() #执行函数
 def show():
    print("执行show函数")
func(show)	

1.2lambda表达式

  • 基本写法
    & 用来表示简单的函数,【函数内部没有复杂代码,只有简单返回值情况】
def func(a,b):
    return a + b
func1=lambda a,b:a+b
func2=lambda : 100
func3=lambda a: a+100
func4=lambda *args,**kwargs: len(args)
#默认会将":"后的结果作为返回

lambda表达式不能定义变量,自己查找变量,没有则向父级查找.[lambda表达式就是一个一行的函数]

#一行实现比较两个值大小,返回大的值
func = lambda a,b: a if a > b else b
n = func(33,5)
print(n)

1.3内置函数

  • 自定义函数
  • 内置函数
    • 强制类型转换 【int,str,bool,list,tuple,dict,set】

    • 数值相关 【max(),min(),float(),abs():求绝对值,sum()】

      • divmod():让两个值相除,得到商和余数 【分页用到】
      • round():转化保留几位销售,四舍五入
    • 输入输出【print,input】

    • 进制相关

      • bin 二进制转换,0b开头
      • oct 八进制 0o开头
      • int 十进制
      • hex 十六进制 0x开头
      # 二进制转十进制
      v1 = '0b1101'
      result = int(v1,base=2)
      print(result)
      # 八进制转十进制
      v1 = '0o1101'
      result = int(v1,base=8)
      print(result)
      # 十六进制转十进制
      v1 = '0x1101'
      result = int(v1,base=16 )
      print(result)
      
    • 其他 【type,len,range,open,id】

    • 编码相关

      • chr() # 根据十进制数字在Unicode编码中找到对应字符
      • ord() # 根据字符在Unicode编码中找到对应的十进制数字
      • 应用:随机验证码的生成【引入random模块 random.randint(10,50)随机返回数字】
    • 高级内置函数

      • map(func,v1) [处理数据]
        & func为一个函数,V1为一个可迭代类型数据,map()函数通过循环V1参数的每个元素,让每个元素执行函数func,将func函数执行的结果添加到一个新列表中返回。
      v1 = [11,22,33,44]
      result = map(lambda x: x+100,v1)
      print(list(result)) # 特殊 ,result是一个object对象
      
      • filter(func,v1) [过滤数据]
        & 循环v1参数中的每个元素并交给func函数执行,如果func函数返回为True,将该元素追加到一个新列表中。
      • reduce(func,v1) [整合数据]
        & 循环v1参数的中的每个元素交给func函数执行,将func函数最终执行的结果返回;【func函数需要两个参数,第一个参数为函数前一次执行的返回值】
        & python3需要导入模块 import functools
      v1 = [1,2,3,4,5]
      result = reduce(lambda x,y: x+y,v1)
      print(result)
      

2.函数中高级

2.1 函数做返回值

  • 闭包
    • 为函数创建一块内存空间维护自己的数据(内部变量供自己使用),方便后面函数执行调用【应用场景:装饰器/SQL Alchemy源码】
    • 函数是由谁创建的,函数就从哪儿开始执行
    • 闭包作用:每次调用函数时,都会为此调用开辟一块内存,内存可以保存自己以后想用的值
  • 把函数当做参数传递
  • 把函数当做返回值
  • 注意:对函数进行赋值
  • 执行函数
    • 函数不被调用,内部代码永远不会执行
    • 执行函数时,会创建一块内存保存自己函数执行的信息【闭包】
      # 函数开辟的内存中未使用name,不是闭包

2.2 递归

  • 递归默认最大次数为1000,可通过sys模块中的方法调整;效率较低
def func(a):
    if a ==5:
        return 100000
    result = func(a+1) + 10
    return result
v = func(1) # 100050

2.3 加密模块

  • hashlib模块
import hashlib
def get_md5(data):
    obj = hashlib.md5("一套随机字符串",encode='utf-8')
    obj.update(data.encode('utf-8')) #python3需要加编码指定
    result = obj.hexdigest()
	return result
  • 密码不不显示,模块 getpass
import getpass
pwd = getpass.getpass('请输入密码:') #密码隐藏不显示
#在终端输入运行(pycharm无法运行不行)
 # getpass 在pycharm终端无法直接运行,如果需要请在命令行或者下方terminal窗口输入py文件运行

第十三节/第十四节

1.装饰器

  • 作用:在不改变原函数内部代码的基础上,在函数执行的前后自动执行某个功能
  • 编写装饰器:
    • @x的作用:
      & 1.执行x函数,把下面func1函数作为x函数的参数传递。
      & 2.将x函数执行的返回值赋值给下面的func1函数名
#装饰器的编写
def x(func):
    def y():
        ret = func()
        return ret
    return y

#装饰器的应用
@x
def func1():
    pass
@x 
def func2():
    pass
  • 应用场景: 为某个或者某些函数做公共功能扩展时使用。
  • 装饰器格式:
def 外层函数(参数):
	def 内层函数(*args,**kwargs):#注意万能参数传递
        return 参数(*args,**kwargs)#注意万能参数传递
    return 内层函数

@外层函数
def index():
    pass
index()

2.推导式

  • 列表推导式
    • 基本格式:变量=[for循环的变量;for循环一个可迭代对象]
vals = [ i for i in 'alex' ]
v1 = [i+100 for i in range(10)]
v2 = [100 for i in range(10)]
v3 = [99 if i >5 else 66 for i in range(10)]
i = [lambda:100+i for i in range(10)]
v4[0]() #109
v = [i for i in range(10) if i > 5]
# 条件成立才append进去
  • 集合推导式
    & v1 = {i for i in 'alex'} # 区别在于集合去重
  • 字典推导式
    & v1 = {'k'+str(i):i for i in range(10)}

3.带参数的装饰器

# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次。把每次结果添加到列表中返回
 import random
def x(num):
    def wrapper(func):
        def inner(*args,**kwargs):
            results = []
            for i in range(num):
                value = func(*args,**kwargs)
                if value > num:
                    results.append(value)
            return results
        return inner
    return wrapper

@x(5)
def index():
    return random.randint(0,10)

r = index()
print(r)

4.模块

4.1 sys模块 【python解释器相关的数据】

  • \n 换行
  • \t 制表
  • \r 回到当前行的起始位置
##进度条
for i in range(1,101):
    msg = "%s%%\r" %i
    print(msg,end='')
  • 转义
    • 字符串前面加字母r,对字符串内容中的特殊字符进行去伪,比如\n不再有它换行的意义。
s = r""D:\code\s21day14\n1.mp4" 
  • sys.argv常用;【获取用户执行脚本时,传入的参数】
    & 获取执行脚本的参数以列表方式存储,默认第0个参数为执行脚本的全路径名
print(arg)
path = sys.argv[1]
print("删除",path)
  • sys.exit(0) ; 终止程序

4.2 shutil模块 【删除目录/文件】

import shutil
# 删除目录
ret = shutil.rmtree("")
# 重命名
shutil.move("原文件名","新文件名")
#压缩文件
shutil.make_archive("压缩后的文件名称","压缩成什么格式","需要压缩的目录")
#解压文件
shutil.unpack_archive("需要解压的文件名",extract_dir="解压到哪个目录",format="解压格式")

4.3 os模块 【和操作系统相关的数据】

  • os.path.exists(path) # 如果path路径存在返回True
  • os.path.abspath() # 获取文件的绝对路径
  • os.path.dirname(file) # 获取文件的上级目录
  • os.path.join(path,file) # 拼接路径
  • os.stas(file).st_size # 获取文件的大小
  • os.listdir(path) # 列出一个目录下的所有文件【不包括子目录,第一层】
  • os.walk() #列出一个目录(包括)子目录下的所有文件【递归方式】
#查看一个目录下所有的文件
import os
listdir = os.listdir("D:\wuhailuo\python_projects\code\python_jichu\模块作业")
# print(listdir)

# 查询显示指定目录下的所有文件,包括子目录下的所有文件
list_file = os.walk("D:\wuhailuo\python_projects\code\python_jichu\模块作业") #得到一个生成器对象,只有当对其循环是给出结果

for a,b,c in list_file: # a:正在查看的目录,b:此目录下的文件夹,c:此目录下的文件
    for filename in c:
        print(os.path.join(a,filename))

15课/16课 :模块知识

补充知识点

  • range函数:python2/3区别:
    • python2:
      • range(10): 在内存中立即将序列值创建
      • xrang(10): 不会在内存中立即创建,只有当在循环时,边循环边创建
    • python3:
      • range(10) = p2中的xrang(10)

1、模块基础知识

1.1 自定义模块

1.1.1 定义模块

  • 定义模块可以把一个py文件或一个文件夹(包)当做一个模块,以便于以后其他py文件的调用。
  • 对于包的定义:【python2/3的区别】
py2: 文件夹中必须有 __init__.py
py3:不需要 __init__.py 【推荐写代码时,加上此文件】

1.1.2 模块调用

  • import 模块 模块.函数()
  • form 模块 import 函数 函数()
  • form 模块 import 函数 as 别名 别名()

总结

  • 模块和要执行的文件在同一目录且需要模块中的很多功能时,推荐使用import导入模块
  • 其他推荐:from 模块 import 模块 模块.函数()
  • 其他推荐:from 模块.模块 import 函数 函数()

1.1.3 补充

  • import

    • import 模块1 模块1.函数()
    • import 模块1.模块2.模块3 模块1.模块2.模块3.函数()
    • 特殊: import 文件夹 内部加载 init.py
  • from xxx import xxx

    • 特殊:from src import xxx 【内部加载src文件夹的__init__.py】
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# 导入模块,加载此模块中所有的值到内存
import os
# 导入模块中某个函数功能
from lizhongwei import func,show
from lizhongwei import * #导入这个模块的所有功能
from lizhongwei import func as f # 避免函数重复覆盖,取别名

1.2 内置模块

1.2.1 os 模块 import os

  • os.mkdir("") 在当前运行脚本的目录创建一个目录(只能生成一级)
  • os.makedirs(r"dd\xx\aa") 递归创建目录
  • os.rename("") 重命名

1.2.2 sys 模块 import sys

  • sys.path 默认Python去导入模块时,按照这个这个值的路径去查找,python文件执行时会将当前文件的路径加载进sys.path里面
import sys
### 给Python添加查找模块的路径
sys.path.append('D:\\ ')    

1.2.3 json模块 【常用】

  • json是一个特殊的字符串。【长的像列表、字符串、字典、数字】
    • json中内部包含的字符串必须要用双引号
  • json字符串最外层必须是一个容器【列表/字典】
    • 元组序列化后成列表,集合不能序列化
  • json格式数据的序列化/反序列化
    • 序列化:将python的值转换成json格式字符串 json.dumps()
    • 反序列化:将json格式字符串 转换Python的数据类型 json.loads()
    • 字典或列表中有中文,序列化要保留中文显示 【ensure_ascii=False】
# 保留中文显示
val = json.dumps(v,ensure_ascii=False)
v = [12,3,4,{'k1':'v1'},True,'asdf']
import json
# 序列化,将python的值转换为json格式的字符串
v1 = json.dumps(v)
s = '["alex",123]'
#反序列化,将json格式的字符串转换为python的数据类型
s1 = json.loads(s)
  • json支持python的数据类型
    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+

1.2.4 pickle模块 【与json模块类似】

  • json 优点:所有语言通用; 缺点:只能序列化基本的数据类型(字符串,列表,字典,数字)
  • pickle 优点:python中所有的东西都能被他序列化(socket对象); 缺点:序列化的内容只有python能认识。
  • pickle.dumps(v) 序列化直接打印是二进制内容,通过pickle.loads(val)处理可正常显示。 【示例下面代码】
  • 字节类型pickle序列化后是一个字节类型 比如 b'xxxx' 【示例下面代码】
v = {1,2,3,4,"abc"}
val = pickle.dumps(v) 
print(val)   # b'\x80\x03cbuiltins\nset\nq\x00]q\x01(K\x01K\x02K\x03K\x04X\x03\x00\x00\x00abcq\x02e\x85q\x03Rq\x04.'
******************************
file_obj = open("x.txt",mode='wb')
data = "abc".encode("utf-8")
print(data,type(data))   # b'abc' <class 'bytes'>
file_obj.write(data)
file_obj.close()

1.2.5 time&datetime时间模块

  • UTC/GMT:世界时间
  • 本地时间:本地时区的时间
  • time模块【获取时间戳】
    • time.time() :时间戳:1970-1-1 00:00 【随机值可以用到】
    • time.sleep(10) 休眠时间/等待秒数
    • time.timezone 时区
  • datetime模块
from datetime import datetime,timezone,timedelta
vl = datetime.now() #当前本地时间
v2 = datetime.utcnow() # 当前UTC时间
tz = timezone(timedelta(hours=7)) # 当前东7区时间
v3 = datetime.now(tz)
  • datetime时间格式转换
from datetime import datetime,timezone,timedelta
v1 = datetime.now()
# datetime时间格式转换字符串
v1.strftime('%Y-%m-%d %H-%M-%S')
#
v2 = datetime.strptime('2020-03-22','%Y-%m-%d')
  • datetime与时间戳的关系
ctime =time.time()
v1 = datetime.fromtimestamp(ctime) # 时间戳转datetime
v2 = datetime.now()
v2.timestamp() #datetime转时间戳

1.3 第三方模块【下载/安装/使用】

1.3.1 前提安装pip包管理工具 ,通过pip安装第三方模块

  • 先需要安装pip,然后通过pip下载安装需要的第三方模块 https://pypi.org
    • 默认在python的安装目录 \Lib\site-packages
# pip.exe所在目录添加到环境变量中
pip install 需要安装的模块名称
  • 常用第三方模块 [requests,xlrd]

1.3.2 源码安装第三方模块

  • 下载源码文件:压缩文件
  • 解压文件并通过命令进入此目录
  • 执行 python3 setup.py(模块安装文件名) build 【编译检查】
  • 执行 python3 setup.py(模块安装文件名) install 【安装】

1.4 自定义模块

1.4.1 步骤

  • 创建xxx.py文件
def func1():
    pass
def func2():
    pass
  • 导入自定义模块并调用功能
import xxx
xxx.func1()
xxx.func2()

2、异常处理

  • 基本语法
try:
    程序处理
except exception as e:
    print("异常处理")
  • try包含的代码执行报错,会直接捕获异常,try块内代码将不再继续执行。所以在循环内部try和try包裹循环,执行结果是不一样的。

17节课/18节课

1、迭代器

  • 迭代器:对可迭代对象中的元素进行逐一获取,且存在__next__方法。
  • 可迭代对象:可被for循环或内部有__iter__方法且返回一个迭代器。
# 列表转换成迭代器的两种方式:
v = [1,2,3,4]
#方式一
v1 = iter(v)
#方式二
v2 = v.__iter__()
# 迭代器逐一获取元素,反复调用__next__()方法
val = v1.__next__()

2、生成器

2.1 生成器

  • 生成器:
    & 函数内部具有yield关键字即为生成器函数
    & 生成器函数不在函数调用时调用,调用函数会返回一个生成器,只有当生成器在被for循环时生成器函数内部代码才会执行,
    每次for循环都会获取yield返回的值
def func():
    yield 1
    print("f1")
    yield 2
    print("f2")
    yield 3
    print("f3")
v = func()
# item只拿函数中yield的值
for item in v:
    print(item)
#输出结果:
# 1
# f1
# 2
# f2
# 3
# f3

  • 可迭代对象:被for循环且此类对象都拥有iter方法,且返回一个迭代器(也可以是生成器)
  • 生成器:可被for循环且拥有__iter__方法,同时也拥有__next__()方法,所以生成器也可以称为特殊的迭代器,或者特殊的可迭代对象
  • 可以通过div(函数对象)来查看函数对象拥有的方法
  • 生成器经典示例,【模拟redis分批读取数据】
#通过生成器读取大数据文件 	[模拟redis数据读取]
import time
"""生成所需数据
with open("data.txt",mode='a+',encoding='utf-8') as fileobject:
    for i in range(1,100):
        fileobject.write("你领取到的号牌是:"+str(i)+"\n")
"""
"""生成器函数"""
"""分批去读取文件中的内容,将文件的内容返回给调用者"""
def func():
    index=0
    while True:
        time.sleep(2)
        with open("data.txt",mode='r',encoding='utf-8') as fileobject: #连接上redis
           li = []
           fileobject.seek(index)
           for i in  range(10):
                line = fileobject.readline().strip()
                if not  line:
                    break
                li.append(line)
           index=fileobject.tell()
        # fileobject.close()
        for i in li:
            yield i

v=func()
for l in v:
    print(l)

2.2 生成器推导式

  • 列表推导式和生成器推导式的区别
#列表推导式
v1 = [i for i in range(10)]
#生成器推导式
v2 = (i for i in range(10))
  • 列表推导式立刻执行,返回for循环0~9的一个列表。
  • 生成器推导式返回的v2是一个生成器,内部for循环没有立刻执行,只有当后面存在for循环调用v2进行循环时,内部for循环才会执行,返回0~9元素
v1 = [lambda : i for i in range(10)] # 列表推导式
v1 = (lambda : i for i in range(10))  # 生成器推导式
# 两者区别
# 列表推导式
def func():
    result = []
    for i in range(10):
        def f():
            return i        
        result.append(f)
    return result
v = func()
for item in v:
    print(item()) # 9*9
#上面函数与下面推导式相等
v1 = [lambda : i for i in range(10)]
for item in v1:
    print(item())

#########################################
# 生成器推导式,
def func():
    for i in range(10):
        def f():
            return i
    yield f     
v = func()
for item in v:
    print(item()) # 0~9
   
# 上面函数与下面推导式相等
v2 = (lambda : i for i in range(10))
for item in v2:
    print(item)

2.3 yield from

  • yield from 后面的值需要返回一个生成器,【比如下面test()函数中的返回值不能是return】
  • 详见代码
def test():
    yield 1
    yield 2
    yield 3

def func():
    yield "alex"
    yield "enki"
    yield from test()
v = func()
for item in v:
    print(item)
# 执行结果
"alex"
"enki"
1
2
3

3、前面知识的补充

py2/py3的区别补充

  • str字符串类型和编码相关
    • py3中,str字符串类型 【一般用于内存中做数据操作,存储编码为unicode】
    • py3中,bytes字节类型 【一般用于网络传输和数据存储,具体编码有执行py文件的文件头编码类型决定】
    • py2中的unicode类型 ---> 为py3中的str类型
    • py2中的 str类型 ----> 为py3中的bytes类型
  • 字典中返回值的不同
    • items
      • py2 返回的列表
      • py3 迭代器 【不能通过索引取值】
    • values
      • py2 返回的列表
      • py3 迭代器 【不能通过索引取值】
    • keys
      • py2 返回的列表
      • py3 迭代器 【不能通过索引取值】
    • 同理 map/filter 也一样

其他知识补充

  • 导入模块
    • import 模块
    • from 模块.模块 import 模块
    • from 模块.模块.模块 import 模块
    • 相对导入 【模块必须有父级目录,不能再根目录下进行该操作】
      • from .. import 模块
      • from . import 模块
    • 注意:文件和文件夹的命名不能是导入的模块名称相同,否则就会直接在当前目录中查找。
  • 主文件【主函数】 (运行的py文件)
    • 通过 属性 name 来区分,属性__name__的值为 __main__ ,表示为主文件
#判断是否为主文件,如果是主文件则执行
if __name__ == '__main__':
    run() #执行入口

猜你喜欢

转载自www.cnblogs.com/enki-1900/p/12684030.html
今日推荐