day9:
函数:
def (形参):
函数体
函数名(实参)
形参:
在函数声明位置的变量
1. 位置参数
2. 默认值参数
3. 混合 位置, 默认值
4. 动态传参, *args 动态接收位置参数, **kwargs 动态接收关键字参数
def func(*args, **kwargs): 无敌传参
pass
*, ** 在形参位置: 聚合
在实参位置: 打散
实参:
在函数调用的时候给函数传递的具体的值
1. 位置参数
2. 关键字参数
3. 混合参数
顺序: 位置, 关键字
传参: 把实参赋值给形参的过程
函数的返回值:return 终止函数的运行 返回值返回给调用方
1. 函数内部不写return, 默认在最后返回None
2. 函数只写了return 返回None
3. return 值 有一个返回值
4. return 值1, 值2, 值3 .... 有多个返回值
习题:(登录注册系统)
写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成文件的修改操作(升级题)。
def func(file_path, old, new):
with open(file_path, mode="r", encoding="utf-8") as f1, \
open(file_path + "_副本", mode="w", encoding="utf-8") as f2:
for line in f1:
s = line.replace(old, new)
f2.write(s)
os.remove(file_path)
os.rename(file_path+"_副本", file_path)
func("student_msg", "$$", "@@")
day10:
1.实参:
1. 位置参数
2. 关键字参数
3. 混合参数
2. 名称空间和作用域
名称空间: 保存名字用的
变量, 函数, 类
1. 内置名称空间:python自己, print, input, len
2. 全局名称空间: 你写的代码从上到下
3. 局部名称空间: 函数, 类, 方法, 其他模块, 对象
作用域
全局作用域
内置 + 全局
局部作用域
局部名称空间
从局部找全局可以. 但是从全局找局部是不可以的
globals() 查看全局作用域中的名字
locals() 查看当前作用域中的名字
3. 函数的嵌套(难点)
每一层都会产生独自的名称空间
4. nonlocal global (会有考试题)
global: 在局部引入全局的内容, 可以升华一个变量为全局变量 全局的东西都是不安全的
nonlocal : 在局部, 引入上一层名称空间中的变量, 如果没有, 继续上一层......
day11:
闭包: 在内层函数中引入外层函数的变量
作用:
1. 保护变量不受侵害(javascript)
2. 让一个变量常驻内存
迭代器
dir() 查看变量能够执行的方法(函数)
Iterator: 迭代器, __iter__(), __next__()
Iterable: 可迭代的, __iter__()
for循环的流程:
it = lst.__iter__()
while 1:
try:
el = it.__next__()
for循环的循环体
except StopIteration:
break
从迭代器中获取数据的唯一方法: __next__()
三个特征:
1. 省内存
2. 惰性机制
3. 只能往前. 不能后退
# 写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组
# 例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]
# 红桃, 黑桃, 梅花, 方块
# A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K
# 笛卡尔积(乘) -> 奠定了关系型数据库的基础
# se = ["红桃", "黑桃", "梅花", "方块"]
# dian = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
# lst = []
# for s in se:
# for d in dian:
# lst.append((s, d))
# print(lst)
# print(len(lst))
'''
1x1=1
2x1=2 2x2=4
3x1=3 3x2=6 3x3=9
....
9x1=9 ....9x9=81
'''
# for i in range(1,10):
# for j in range(1, i+1):
# print("%sx%s=%s" % (i, j, i*j), end=" ")
# print()
# for i in range(1, 6):
# for j in range(i):
# print("*", end="")
# print()
it = lst.__iter__()
print(it.__next__())
# collections 关于集合类的相关操作
# Iterable : 可迭代的
# Iterator : 迭代器
lst = ["秦始皇", "汉武帝", "孝文帝", "隋炀帝", "李世民"]
from collections import Iterable, Iterator
print(isinstance(lst, Iterable)) # True
print(isinstance(lst, Iterator)) # False
print(isinstance({1,2,3}, Iterable)) # True, 可以使用for循环
day12
1、迭代器
__iter__() 获取迭代器
__next__() 下一个
dir()函数不带参数时,返回当前范围内的变量、方法和定义的类型列表
2、推导式
字典推导式和集合推导式 没有元组推导式
# {结果 for循环 if判断}
# {结果 for循环 if判断}
# lst = [11, 22, 33] # => {0:11, 1:22, 2:33}
# dic = {i:lst[i] for i in range(len(lst)) }
# print(dic)
过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
# lst = ["alex", 'db', '2b', "wusir", 'sb', "taibai","nezha", "ritian"]
# print([ el.upper() for el in lst if len(el) >= 3])
用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb
name=['oldboy','alex','wusir']
print(list(map(lambda n: n+"_sb" , name)))
print("__iter__" in dir(m)) # True
# print("__next__" in dir(m)) # True #带参数时,返回参数的属性、方法列表
3、生成器
生成器函数有什么用?省内存
本质就是迭代器
两种方式写生成器
1. 生成器函数
2. 生成器表达式
send()可以给上一个yield位置传值
send()不可以在第一个位置和最后一个位置出现
最后的yield后的代码是可以执行的但是会报错. StopIteration
生成器函数里不要写return
第一种
# 生成器函数. 就是把return换成yield
# def gen():
# print("爽歪歪")
# yield "娃哈哈" # 可以让我们的函数分段运行
# print("酸酸乳")
# yield "AD钙奶"
# print("黄焖鸡米饭")
第二种
# ret = gen() # 不会执行你的函数, 获取到生成器对象
# # 迭代器不能等价代换
# print(ret) # <generator object gen at 0x00000195518CFE60> generator 生成器
# print(ret.__next__()) # 必须执行__next__()才可以触发生成器的运行 娃哈哈
def gen():
lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
yield from lst
g = gen() # 获取生成器
for el in g: # 从生成器获取数据
print(el) # 打印 从lst第一个字符打印开始,四行
打印图形
# 6行
# 行号1 2 3 4 5 6
# 空白5 4 3 2 1 0
# 星号1 3 5 7 9 11
# 6-i
# *
# ***
# ***** # 2 * i - 1
# *******
# *********
# ***********
# n = int(input("请输入你要打印多少行"))
# for i in range(1, n+1):
# # 方案一
# for k in range(n-i):
# print(" ", end="")
# for j in range(2 * i - 1):
# print("*", end="")
# print() # 换行
#
#
# # 方案二
# print(" " * (n - i) + "*" * (2 * i - 1))
day13:内置函数(略)默写15个内置函数及
day14:
匿名函数lambda 参数: 返回值
1. sorted
排序
sorted(Iterable, key, reverse)
2. filter
筛选
filter(function, Iterable)
3. map
映射
map(function, Iterable)
4. 递归
自己调用自己
5. 二分法(递归的应用)
开头
结尾
中间
二分法(重点)
# lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963] # 时间复杂度. n
# # 让用户输入一个数n. 判断这个n是否出现在lst中
# n = int(input("请输入一个数字n:")) # 56
#
# left = 0 # 左边界
# right = len(lst) - 1 # 末尾的索引 右边界
# while left <= right: # 当左边界大于右边界结束循环
# mid = (left + right) // 2 # 求中间的索引坐标
# if n < lst[mid]: # 判断你的数字和中间数的大小比较 .
# right = mid - 1 # 右边界往左移动
# elif n > lst[mid]:
# left = mid + 1 # 左边界往右移动
# else:
# print("找到了") # 找到了目标数字
# break
# else: # 当左比右大, 循环结束. 没有找到目标数
# print("没找到")
递归函数(操作文件夹的那个代码)
函数的递归深度:1000 不同的操作系统深度不一样,windows在998
列出文件夹内的所有文件
import os
os.listdir()
os.path.join() 拼接路径
os.path.isdir() 判断是否是文件夹
os.remove()
os.rename()
day15:
class类名首字母大写.
__init__(__new__)构造方法. 在创建的对象的时候由系统自动访问这个方法
self: 自己. 自身. 类的对象. 当前正在创建的对象
谁调用的这个方法. self就是谁
面向对象的三大特征: 封装, 继承, 多态
1. 封装
对属性封装
self.xxx = xxxx
对方法封装
2. 继承
子类可以自动拥有父类中除了私有内容外的其他所有内容
多继承class(亲父,干爹) 先调用亲父的方法,没有再从干爹那找
子类在父类的基础上扩展了一些功能. 派生
3. 多态
同一个对象多种形态.(在python中多态的效果感受不够明确)
只要包含了xxx功能的内容都可以试用. 鸭子模型 -> 多态性
day16:
面向对象:以对象为中心. 所有的东西都是对象. 操纵的是对象. 让对象去完成相应的操作
面向过程: 以我为中心. 按照事物发展的流程顺序来写代码
优点: 代码量少, 简单
缺点: 扩展性差
成员
变量
1. 实例变量. 对象.xxx = xxx 实例变量 -> 字段 -> 属性. 给对象用的
写在__init__上边的那个变量
2. 类变量. 直接写在类中的变量就是类变量. 类变量一般用类名来访问. 对象*性的属性提取出来.
方法 类变量的修改只能通过类名来完成
1. 实例方法. 对象.方法() 通过【对象】来调用类里面的方法
2. 类方法. 类名.方法()@classmethod
3. 静态方法. 类名.方法()@staticmethod # 在类中定义的一个普通函数
属性@property
把方法转化成属性.
对象.属性
私有
__作为前缀
在自己类中可以随意访问. 但是出了类任何人都不可以访问这个私有内容
day17:
类与类之间的关系
1. 依赖关系. 通过参数的传递把另外一个类的对象传递进来
2. 关联关系, 组合, 聚合. 通过属性设置来维护两个对象的关系
def __init__():
self.stuList = []
def __init__():
self.teacher = teacher
3. 继承关系
self: 谁调用的,. self就是谁
# 依赖关系:A调用C里面的方法,需要有个方法参数(形式参数)接收C的实例变量
# class A:
# def func1(self, anumber):
# print("I'm Func1")
# anumber.func3()
# def func4(self):
# print("This is func4")
# class B:
# def func2(self, bnumber):
# print("I'm Func2")
# bnumber.func3()
# class C:
# def func3(self):
# print("I'm Func3")
# def func5(self, cnumber):
# print("I'm Func5")
# cnumber.func4()
#
# a = A()
# b = B()
# c = C()
# a.func1(c) # func1, func3
# b.func2(c) # 2 3
# c.func5(a) # 5 4
# 关联关系:
# class B:
# def __init__(self, name, lst=None):
# self.name = name
# if lst == None: # 判断传递过来的参数是否是空
# self.lst = []
# else: # 传递过来的是一个列表
# self.lst = lst
# def tianjia(self, student):
# self.lst.append(student)
# def display(self):
# for s in self.lst: # s 是老师的学生
# print(s.name)
# class C:
# def __init__(self, id, name, teacher=None):
# self.name = name
# self.id = id
# self.teacher = teacher
# b = B("老师NO1")
# c1 = C("1", "Andorid1", "老师1")
# c2 = C("2", "Andorid2", "老师2")
# c3 = C("3", "Andorid3", "老师3")
# b.tianjia(c2)
# b.display()
# 继承关系:Foo继承了Base,Base__init__有多少参数需要传进去,Foo实例变量就要传多少参数进去
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print(111, self.num)
class Foo(Base):
def func2(self):
print(222, self.num)
# b = Base(1)
# b.func2()
f = Foo(2)
f.func2()
# f = Foo(1)
# f.func1()
# lst = [Base(1), Base(2), Foo(3)]
# for obj in lst:
# obj.func2()
# 111 1
# 111 2
# 222 3
4. 特殊成员
__init__() 初始化方法
__new__() 构造方法
__call__() 对象()
__add__() +
__getitem__ 对象[]
__setitem__ 对象[] = 值
__delitem__ del 对象[]
__del__ del 对象. 析构
__len__ len(对象)
__iter__ for. iter()
__next__ next()
__dir__ dir()
__getslice__ 对象[::]
__hash__ hash()
__class__
__dict__ 查看当前想的属性
显示页码习题 (注意)
day18:
1. issubclass, type, isinstance
issubclass 判断xxx类是否是xxx类的子类 \
type 获取到xxx对象的类型
isinstance 判断xxx对象是否是xxx类型的(向上判断)
2. 如何判断一个方法或者一个函数(FunctionType, MethodType)
from types import FunctionType, MethodType
print(isinstance(xx, FunctionType)))
print(isinstance(xx, MethodType)))
结论 :
1. 实例方法:
用类名访问. 函数
用对象访问. 方法
2. 静态方法
都是函数
3. 类方法
都是方法
3. 反射(重点)
hasattr(对象, 属性(字符串))
getattr(对象, 属性(字符串)) 从对象中获取到xxx属性
setattr(对象, 属性, 值)
delattr(对象, 属性) 从对象中删除xxx属性
4. md5加密
import hashlib
obj = hashlib.md5(加盐)
obj.update(铭文的bytes)
obj.hexdigest() 获取密文