Python 基础(下)

"""
函数: 对某一个特定的功能或者代码块进行封装. 在需要使用该功能的时候直接调用即可

定义:
def 函数的名字():
	被封装的功能或者代码块->函数体

调用:
函数的名字()

好处: 让程序更加简洁. 代码更加合理
"""


def buy_cai():  # 定义函数
	print("1. 打车")
	print("2. 去菜市场")
	print("3. 讨价还价")
	print("4. 回家")


buy_cai()
print("哄哄孙子")
buy_cai()
print("冲洗马桶")
buy_cai()
print("打打老头")

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 函数的参数 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //

"""
参数: 可以在函数调用的时候. 给函数传递一些信息

分类:
	1. 形参, 在函数定义的时候. 需要准备一些变量来接收信息
		1. 位置参数, 按照位置一个一个的去声明变量
		2. 默认值参数,  在函数声明的时候给变量一个默认值, 如果实参不传递信息. 此时默认值生效, 否则就不生效
		3. 动态传参.
			 1. *args,  表示接收所有的位置参数的动态传参----> 元组
			 2. **kwargs, 表示接收所有的关键字的动态传参---> 词典

		顺序*: 位置 > *args > 默认值 > **kwargs

		上述参数可以随意搭配使用

	2. 实参, 实际在调用的时候传递的信息
		1. 位置参数. 按照位置进行传递参数
		2. 关键字参数. 按照参数的名字进行传递参数
		3. 混合参数.
			顺序: 位置参数放前面, 关键字参数放后面 -> 否则报错! 官方不让这么干
		实参在执行的时候. 必须要保障形参有数据



"""


# 1.骂谁?  2.骂道什么程度?
def maren(ren, lvl):  # 形参
	print("1. 怒目而视", ren)
	print("2. 验证交涉", ren)
	if lvl > 99:
		print("3. 死不要脸")
	else:
		print("3. 你愁啥")
	print("4. 骂完手工")


maren("破键盘", 188)  # 在调用函数的时候. 才能知道到底骂谁, 骂道什么程度  -> 实参
maren("破鼠标", 10)
maren("破电脑", 999)

请用函数编写一个计算器, 能计算 + - * / 四则运算
a + b


def jisuan(a, opt, b):
	if opt == "+":
		print(a + b)
	elif opt == '-':
		print(a - b)
	elif opt == '*':
		print(a * b)
	elif opt == '/':
		print(a / b)
	else:
		print("滚犊子")


jisuan(999, "+", 666)
jisuan(999, "-", 666)
jisuan(999, "*", 666)
jisuan(999, "/", 666)
jisuan(999, "^&*", 666)

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *实参分类 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //

def chi(zhu, fu, tang, tian):
	print(zhu, fu, tang, tian)


chi("大米饭", "西红柿炒鸡蛋", "紫菜蛋花汤", "哈根达斯")
chi(zhu="小米饭", tang="胡辣汤", fu="韭菜炒大腰子", tian="老中街冰棍")
chi("小米饭", "胡辣汤", tang="韭菜炒大腰子", tian="老中街冰棍")  # 可以
chi("小米饭", "胡辣汤", fu="韭菜炒大腰子", tian="老中街冰棍")  # 也不行!!fu 被赋值了两次!会导致某个形参没有实参对应,不行
chi()  # 实参在执行的时候. 必须要保障形参有数据

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *形参分类 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //

def luru(name, age, gender="男"):
	print(name, age, gender)


luru("张三", 18)
luru("李四", 28)
luru("王二麻子", 38)
luru("吴老二", 14)
luru("赵敏", 12, "女")  # '女' 会覆盖默认形参:'男'
luru("周芷若", 11, "女")


def chi(*food):  # * 表示位置参数的动态传参, *接收到的值会被统一放在一个元组里面
	print(food)


chi('大米饭', "烧茄子", '紫菜蛋花汤', "哈根达斯")  # ('大米饭', '烧茄子', '紫菜蛋花汤', '哈根达斯')
chi("大米饭")  # ('大米饭',)


def chi(**food):  # ** 表示接收关键字的动态传参, 接收到的所有参数都会被处理成字典
	print(food)


chi(fu="木须柿子", zhu="小米饭")  # {'fu': '木须柿子', 'zhu': '小米饭'}


def func(a, b, c="哈哈", *args, **kwargs):  # 如果这种情况,要么:哈哈  ()   要么,xx (xxx)
	print(a, b, c, args, kwargs)  # 也就是说,默认值:哈哈 和 元组 冲突!!不行!


func(1, 2, 3, 4, 5, 6, hello=456, hahalou=654)  # 但凡有2个数字以上,哈哈 就没有了,就有元组
可以推断出:*args
必须在
c = "哈哈"
前面!!!
func(1, 2, hello=456, hahalou=654)  # 1 2 哈哈 () {'hello': 456, 'hahalou': 654}


# 何时能产生默认值:通过关键字指定的方式进行修改
def func(a, b, *args, c="哈哈", **kwargs):
	print(a, b, c, args, kwargs)


func(1, 2, 3, 4, 5, hello=456, hahalou=654)  # 这种情况,c永远是默认值:"哈哈"
func(1, 2, 3, 4, c="呵呵", hello=456, hahalou=654)  # 这种方式可以修改c
func(1, 2, 3, 4, hello=456, hahalou=654, c="呵呵")  # 都可以!! 这里c,形参上有默认值。所以代替默认值。位置在后面那个地方都行
func(1, 2, 3, 4, hello=456, c="呵呵", hahalou=654)  # 这也可以
func(1, 2, c="呵呵", 3, 4, hello=456, hahalou=654)  # 这肯定不行哈哈


def func(*args, **kwargs):  # 没有限制的接收任何参数
	print(args, kwargs)


func()  # (), {}
func(1)  # (1, ), {}
func(1, 2, 3, 4, 4, a=2)  # (1,2,3,4,4), {"a":2}
func(1, 2, 3, 4, c=4, a=2)  # (1,2,3,4), {"c":4, "a":2}

stu_lst = ["流川枫", '樱木', "大老王", "隔壁二老王"]


def func(*args):
	print(args)


func(stu_lst)
func(stu_lst[0], stu_lst[1], stu_lst[2], stu_lst[3], )
func(*stu_lst)  # *在实参位置, 是把列表打散成位置参数进行传递

stu_lst = {"c": 4, "a": 2}


def func(**args):
	print(args)


func(**stu_lst)  # {'c': 4, 'a': 2}        ** 在实参位置, 可以把字典自动转化成关键字参数进行传递
func(c=5, a=7, p=8)  # {'c': 5, 'a': 7, 'p': 8}
# func( stu_lst )     # 不行!!!报错。因为 **args 接受的是单个单个的字典。
print(*stu_lst)  # c a


def fun(args):
	print(args)


fun(stu_lst)  # {'c': 4, 'a': 2}    当然可以

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 返回值 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //

"""
	返回值: 函数执行之后. 会给调用方一个结果. 这个结果就是返回值

	关于return:
		函数只要执行到了return. 函数就会立即停止并返回内容. 函数内的return的后续的代码不会执行
		1. 如果函数内没有return , 此时外界收到的是None
		2. 如果写了return
			1. 只写了return, 后面不跟数据, 此时接收到的依然是None  -> 相当于break
			2. return 值 , 此时表示函数有一个返回值, 外界能够收到一个数据 -> 用的最多
			3. return 值1, 值2, 值3....., 此时函数有多个返回值, 外界收到的是元组, 并且, 该元组内存放所有的返回值
"""


def func(a, b):
	# print(a + b)
	return a + b


ret = func(10, 20)
print(ret * 3)


def func():
	pass


# return None     (默认)
ret = func()
print(ret)  # None


def func():
	print(123)
	return  # 会让程序停止.  后续代码不会继续执行. 有点儿像循环里面的break
	print(456)  # 不会执行


ret = func()
print(ret)  # None

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *Python
的内置函数 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //

"""
https://www.processon.com/view/link/5dbfcf15e4b09df5518ee260
内置函数: 直接能拿来用的函数
print
input
"""
print("hello world")

s = "123"
i = int(s)
b = bool(s)
f = float(s)
complex
复数: 实部 + 虚部

# bin, oct, hex
a = 18  # 十进制
print(bin(a))  # 0b10010
print(oct(a))  # 0o22
print(hex(a))  # 0x12

a = 0b10010
print(int(a))  # 二进制转化成十进制

# sum, min, max, pow
a = 10
b = 3
print(pow(a, b))
print(a ** b)  # 次幂

lst = [12, 456, 32, 18, 64, 57]
print(max(lst))
print(min(lst))
print(sum(lst))

# lst[]内部应该是:
lst = []
for item in lst:
	lst.append(item)

s = {1, 2, 3, }
lst = list("呵呵哒")  # 内部一定会有一个循环(for)
print(lst)  # ['呵', '呵', '哒']

s = slice(1, 4, 2)  # [1:4:2]
print("我的天哪我去你的"[s])  # 的哪

format, ord, chr
format
格式化
a = 18
print(format(a, "08b"))  # b: 二进制, o: 八进制, x: 十六进制

a = "中"  # python的内存中使用的是unicode
print(ord(a))  # 2013    中国的中字在unicode中码位是20013
print(chr(20013))  # 给出编码位置. 展示出文字
for i in range(65536):
	print(chr(i) + " ", end="")

enumerate, all, any
print(all([1, "123", '豆沙包']))  # True   当成and来看  t and t and t
print(any([0, "", '']))  # False   当成or来看

lst = ["张无忌", "张翠山", "张三丰", "张大大"]

for item in enumerate(lst):
	print(item)
# (0, '张无忌')
# (1, '张翠山')
# (2, '张三丰')
# (3, '张大大')

for index, item in enumerate(lst):
	print(index, item)
# 0  张无忌
# 1  张翠山
# 2  张三丰
# 3  张大大

for i in range(len(lst)):
	print(i, lst[i])
# 0  张无忌
# 1  张翠山
# 2  张三丰
# 3  张大大

s = "呵呵哒"
print(hash(s))  # 一定是一个数字 -> 想办法转化成内存地址. 然后进行数据的存储 -> 字典(集合)哈希表

print(id(s))  # 直接获取内存地址
# 细节: id(s)  hash(s) 每次运行都更新一次

print(help(str))  # 返回源码   你可以点住:ctrl ,再点击目标点,可以查看源码

s = "呵呵哒"
print(help(s))
print(dir(s))  # 当前这个数据能执行哪些操作


def func():
	return 1, 2, 3, 4


ret = func()
print(ret)  # (1, 2, 3, 4)

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *函数
下 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //

"""
	函数的嵌套
	变量的作用域
	闭包
	装饰器
		def wrapper(fn):
			def inner(*args, **kwargs);
				ret = fn(*args, **kwargs)
				return ret
			return inner

		@wrapper
		def func():
			pass
	迭代器
	生成器
		yield

		g = (x for x in xx)
	推导式
	匿名函数
	python内置函数_下 sorted, filter, map
"""

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 作用域 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //

"""
作用域: 变量的访问权限

总结: 里面访问外面没问题, 外面访问里面不能直接访问到
"""
a = 10  # 全局变量 -> 全局作用域
print(a)


def func():  # 全局的一个函数
	b = 20  # 局部变量, 局部作用域
	print(a)  # 10


func()  # 10
print(b)  # 不行!!报错!!外部不能访问内部


def func3():
	func()  # 可以


func3()


def func():
	c = 10086
	return c  # 如果想要在函数外面访问到函数内部的东西. 必须要return


c1 = func()
print(c1)

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *函数嵌套 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //

"""
函数可以嵌套函数

综上:
	1, 函数可以作为返回值进行返回
	2, 函数可以作为参数进行互相传递
	函数名实际上就是一个变量名, 都表示一个内存地址

"""


def func1():
	pass


def func2():
	func1()  # 这个叫函数的调用. 不叫嵌套

func2()


def func1():
	b = 20
	def func2():  # 函数的嵌套, 局部变量
		pass
	print(b)
	func2()  # 局部的东西. 一般都是在局部自己访问使用的

print(func1())


def func1():
	print(1)
	def func2():
		print(3)
		def func3():
			print(5)
		print(4)
		func3()
		print(6)
	print(2)
	func2()
	print(7)

func1()   # 1234567



def func():
	def inner():
		print(123)

	print(inner)  # <function func.<locals>.inner at 0x000001A315278B80>
				 #    函数    func   内部     inner       地址
	return inner  # 返回的是一个函数, 此时我们把一个函数当成一个变量进行返回的


b1 = func()  # b1是func的内部inner
print(b1)
b1()


def func():
	def inner():
		def aa():
			print(123)

		print(aa)

	return inner  # 返回的是一个函数, 此时我们把一个函数当成一个变量进行返回的


b1 = func()  # b1是func的内部inner
print(b1)  # <function func.<locals>.inner at 0x000001AE076B8B80>
b1()  # <function func.<locals>.inner.<locals>.aa at 0x000001AE076B9800>


def an():
	print(123)


print(an)  # <function an at 0x00000176887604A0>
an()  # 123
bn = an
print(bn)  # <function an at 0x00000176887604A0>
bn()



分析1:

def func():
	def inner():
		def aa():
			def gg():
				print(123)

		print(aa)

	return inner  # 返回的是一个函数, 此时我们把一个函数当成一个变量进行返回的

print(func)  # <function func at 0x000002D00C6504A0>
print(func())  # <function func.<locals>.inner at 0x000002D00C778B80>
print(func()())  # <function func.<locals>.inner.<locals>.aa at 0x000002D00C779800>

b1 = func()  # b1是func的内部inner
print(b1)  # <function func.<locals>.inner at 0x000001AE076B8B80>
b1()       # <function func.<locals>.inner.<locals>.aa at 0x0000020A3C319800>  等价于 inner()
			# func()=inner=b1    b1()=inner()

func()()  # func()---->返回: inner    inner()---> print(aa)
# <function func.<locals>.inner.<locals>.aa at 0x0000021BC6429800>

print(func())  # 等价于 print(inner)      print(inner()) 等价于 print(aa)   下面的分析2可以验证
				# func=func  func()=inner  func()()=inner()  inner=inner

func()  # 没有输出

a = func
print(a)  # <function func at 0x000001DF965404A0>
print(func)  # <function func at 0x000001DF965404A0>

分析2:

def func():
	def inner():
		print(inner, 5)

	print(inner)
	return inner


func()  # <function func.<locals>.inner at 0x000001535E2D8B80>

print(func())  # <function func.<locals>.inner at 0x000001535E2D9800>
				# <function func.<locals>.inner at 0x000001535E2D9800>

func()()  # <function func.<locals>.inner at 0x000001535E2D98A0>
		   # <function func.<locals>.inner at 0x000001535E2D98A0> 5




# 代理模式
def func(an):  # 此时an收到的是一个函数
	print(an)  # <function target at 0x000001BE95768B80>
	an()  # 执行这个函数      # 我是target

def target():
	print("我是target")

c = 456
func(target)  # 实参可以是函数

//************************************  global  nonlocal ****************************************************//

"""
global : 在局部. 引入全局变量
nonlocal: 在局部, 引入外层的局部变量
"""

a = 10
def func():
	a = 20  # 创建一个局部变量. 并没有去改变全局变量中的a
func()
print(a)  # 10


a = 10
def func():
	# 此时我就想在函数内部修改全局的变量a
	global a  # 把外面的全局变量引入到局部
	a = 20  # 创建一个局部变量. 并没有去改变全局变量中的a
func()
print(a)   # 20

def func():
	a = 10
	def func2():
		a = 20
	func2()
	print(a)  # 10

func()  # 10


def func():
	a = 10
	def func2():
		nonlocal a  # 向外找一层. 看看有没有该变量. 如果有就引入, 如果没有, 继续向外一层, 直到全局(不包括)
					# 把 a=10拽过来
		a = 20
	func2()
	print(a)

func()  #20


我想验证一下:如果没有, 继续向外一层, 直到全局(不包括)  写了一个调用函数:
def func():
	a = 10
	def func2():
		def gg():
			def aa():
				nonlocal a  # 向外找一层. 看看有没有该变量. 如果有就引入, 如果没有, 继续向外一层, 直到全局(不包括)
				# 把 a=10拽过来
				a = 20
		gg()
			aa()
		print(a)
	func2()

func()  # 20

哈哈哈哈这个有问题。以后再看看这个吧。吐了~~

//********************************************  闭包   ******************************************************//

def func():
	a = 10
	def inner():
		print(5)
		return a
	return inner

a=func()    # 只是返回了 inner 而已!!!不会输出5!!
			# 此时,这个func()返回的 inner 函数,就是:闭包函数

"""
闭包: 本质, 内层函数对外层函数的局部变量的使用. 此时内层函数被称为闭包函数
	1. 可以让一个变量常驻与内存
	2. 可以避免全局变量被修改
"""


def func():
	a = 10
	def inner():
		nonlocal a
		a += 1
		return a
	return inner


a=func()   # func()=inner=a     10
a()   #   func()()=inner()=a()    偷偷的:a+1=11
print(a())     # 12

						 这里有个坑,我想了一会儿,明白了  通过上面的推理,我们可以知道:a()==func()()
请运行一下,下面两个程序:

a=func()      # 10   这时func里的print(a)   都对同一个inner进行操作!!
print(a())      # 11
print(a())      # 12
print(a())      # 13

和
print(func()())    # 10    11   func里的print(a:10),内部进入了inner,a--->11    每次对新的inner进行操作,所以一直会重复 10  11
print(func()())    # 10    11   func里的print(a:10),内部进入了inner,a--->11
print(func()())    # 10    11   func里的print(a:10),内部进入了inner,a--->11

		为什么等价的东西,会出现不一样的情况呢?很简单。因为,你上面的 三个a()是在对同一个inner()进行操作
			而下面的三个func()(),每次都对新的func()里面的inner()进行操作。

//******************************  装饰器  ********************************************************************//

"""
内容回顾:
	1. 函数可以做为参数进行传递
	2. 函数可以作为返回值进行返回
	3. 函数名称可以当成变量一样进行赋值操作

装饰器:   -> 要求记住最后的结论
	装饰器本质上是一个闭包
	作用:
		在不改变原有函数调用的情况下. 给函数增加新的功能.
		直白: 可以在函数前后添加新功能, 但是不改原来的代码

	在用户登录的地方, 日志.
	通用装饰器的写法:
		def wrapper(fn):   wrapper: 装饰器, fn: 目标函数
			def inner(*args, **kwargs):
				# 在目标函数执行之前.....
				ret = fn(*args, **kwargs)   #   执行目标函数
				# 在目标函数执行之后.....
				return ret
			return inner     千万别加()

		@wrapper
		def target():
			pass

		target()  #  =>  inner()

	一个函数可以被多个装饰器装饰.
	@wrapper1
	@wrapper2
	def target():
		print('我是目标')

	规则和规律 wrapper1 wrapper2 TARGET wrapper2 wrapper1
"""

def func():
	def inner():
		print("123")
	return inner

ret = func()
ret()


def func1():
	print("我是函数1")

def func2():
	print("我是函数2")

func1 = func2   # 函数可以直接传递
func1()  # 等价于 func2()


def guanjia(game):
	def inner():
		print("打开外挂")
		game()  # 玩起来了
		print('关闭外挂')
	return inner


@guanjia     # 相当于 play_dnf = guanjia(play_dnf)
def play_dnf():
	print('你好啊, 我叫赛利亚, 今天又是美好的一天!')


@guanjia
def play_lol():
	print("德玛西亚!!!!!!")


# play_dnf = guanjia(play_dnf)  # 让管家把游戏重新封装一遍. 我这边把原来的游戏替换了
# play_lol = guanjia(play_lol)  # 让管家把lol也重新封装一下.

play_dnf()  # 此时运行的是管家给的内层函数inner
play_lol()


#*****************************

def guanjia(game):
	#         *, **表示接收所有参数, 打包成元组和字典
	def inner(*args, **kwargs):  # inner添加了参数, args 一定是一个元组  kwargs 一定是字典 (admin, 123456, "大盖伦")
		print("打开外挂")
	#        *, ** 表示把args元组和kwargs字典打散成 位置参数以及关键字参数传递进去
		game(*args, **kwargs)  # 玩起来了  # game('admin', '123456', "大盖伦")
		print('关闭外挂')
	return inner


@guanjia  # play_dnf = guanjia(play_dnf)
def play_dnf(username, password):
	print("我要开始玩儿dnf了. ", username, password)
	print('你好啊, 我叫赛利亚, 今天又是美好的一天!')


@guanjia
def play_lol(username, password, hero):
	print("我要开始玩儿lol了. ", username, password, hero)
	print("德玛西亚!!!!!!")


play_dnf("admin", "123465")  # inner
play_lol("admin", "456789", "大盖伦")

//***********************************************   返回值    ************************************************

def guanjia(game):
	def inner(*args, **kwargs):
		print("打开外挂")
		ret = game(*args, **kwargs)  # 这里是目标函数的执行, 这里是能够拿到从目标函数返回的返回值的.
		print('关闭外挂')
		return ret
	return inner


@guanjia
def play_dnf(username, password):
	print("我要开始玩儿dnf了. ", username, password)
	print('你好啊, 我叫赛利亚, 今天又是美好的一天!')
	return "一把屠龙刀"


def play_lol(username, password, hero):
	print("我要开始玩儿lol了. ", username, password, hero)
	print("德玛西亚!!!!!!")


ret = play_dnf("admin", "123465")  # inner
print(ret)



def wrapper1(fn):  # fn: wrapper2.inner
	def inner(*args, **kwargs):
		print("这里是wrapper1 进入")  # 1
		ret = fn(*args, **kwargs)  # wrapper2.inner
		print("这里是wrapper1 出去")  # 5
		return ret
	return inner

def wrapper2(fn):  # fn: target
	def inner(*args, **kwargs):
		print("这里是wrapper2 进入")  # 2
		ret = fn(*args, **kwargs)  # taget
		print("这里是wrapper2 出去")  # 4
		return ret
	return inner


@wrapper1  # target = wrapper1(wrapper2.inner)   =>  target: wrapp1.inner
@wrapper2  # target = wrapper2(target)   => target: wrapper2.inner
def target():
	print('我是目标')  # 3

target()


"""
这里是wrapper1 进入
这里是wrapper2 进入
我是目标
这里是wrapper2 出去
这里是wrapper1 出去
"""

//***************************************************  实战    ************************************************//
login_flag = False

def login_verify(fn):
	def inner(*args, **kwargs):
		global login_flag
		if login_flag == False:  # ????
			# 这里完成登录校验
			print('还未完成用户登录操作')
			while 1:
				username = input(">>>")
				password = input(">>>")
				if username == "admin" and password == "123":
					print("登录成功")
					login_flag = True    # 记录登录的状态  下次进行操作时,不用修改
					break
				else:
					print("登录失败, 用户名或密码错误")
		ret = fn(*args, **kwargs)  # 后续程序的执行
		return ret
	return inner



@login_verify
def add():
	print("添加员工信息")

@login_verify
def delete():
	print("删除信息")

@login_verify
def upd():
	print("修改信息")

@login_verify
def search():
	print("查询员工信息")

add()
upd()
delete()
search()

//***************************************  迭代器   *********************************************************//

"""
for 变量 in 可迭代:
	pass

iterable: 可迭代的东西
iterator: 迭代器
str, list, tuple, dict, set, open()

可迭代的数据类型都会提供一个叫迭代器的东西. 这个迭代器可以帮我们把数据类型中的所有数据逐一的拿到

获取迭代器的两种方案:
	1. iter() 内置函数可以直接拿到迭代器
	2. __iter__()   特殊方法

从迭代器中拿到数据:
	1. next() 内置函数
	2. __next__() 特殊方法

for里面一定是要拿迭代器的. 所以所有不可迭代的东西不能用for循环
for循环里面一定有__next__出现

总结: 迭代器统一了不同数据类型的遍历工作

迭代器本身也是可迭代的
迭代器本身的特性:
	1. 只能向前不能反复
	2. 特别节省内存
	3. 惰性机制     什么时候访问下一个,采取执行。不然,一直呆着

"""

for item in 1234:
	print(item)    # 会报错!!! 因为 1234 没有自带的迭代器,无法遍历。

s = 123
it = iter(123564646)  #  不行!!! 可以转化成 iter("123564644")

for mm in it:
	print(mm)



it = iter("你叫什么名字啊")

print(it)    # <str_iterator object at 0x0000026C0F4E9AB0>
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))

print(next(it))  # StopIteration: 迭代已经停止了. 不可以再次从迭代器中拿数据了  报错


it = "呵呵哒".__iter__()

print(it)    # <str_iterator object at 0x0000020CD80AA6B0>
print(it.__next__())
print(it.__next__())
print(next(it))   # 都行



# 模拟for循环工作原理:
s = "我是数据"
it = s.__iter__()  # 拿到迭代器
while 1:
	try:
		data = it.__next__()
		print(data)  # for循环的循环体
	except StopIteration:   # 要用特定专属的异常~
		break
print(123456)



s = "你好啊, 我叫赛利亚"
it = s.__iter__()

for mm in it:   # 说明,迭代器可以被迭代(通过 for 循环遍历)            # for mm in s:   也可以!!
	print(mm)

//*******************************************    生成器  ***************************************************//

"""
生成器(generator):
	生成器的本质就是迭代器

	创建生成器的两种方案:
		1. 生成器函数
		2. 生成器表达式

	生成器函数
		生成器函数中有一个关键字yield
		生成器函数执行的时候, 并不会执行函数, 得到的是生成器.

		yield: 只要函数中出现了yield. 它就是一个生成器函数
			作用:
				1. 可以返回数据
				2. 可以分段的执行函数中的内容, 通过__next__()可以执行到下一个yield位置
		优势:
			用好了, 特别的节省内存


	生成器表达式 -> 一次性的
		语法: (数据 for循环 if)

"""
def func():
	print(123456)
	return 999  # yield也有返回的意思.

func()     # 输出:123456



def func():
	print(123456)
	yield 999  # yield也有返回的意思.

func()   # 不会输出!! 此时,变成了生成器函数。不是普通函数



def func():
	print(123456)
	yield 999

ret = func()   # 不会输出
print(ret)  # <generator object func at 0x115f2dbd0>

ret.__next__()   # 123456   返回 999
print(ret.__next__())  # 123456   999
						# yield只有执行到next的时候才会返回数据

print(ret.__next__())  # StopIteration   只有一个 yield ,所以只能有一个 ret.__next__()



def func():
	print(123)  # 1
	print(888)  # 2
	yield 666  # 3
	print(444)  #4
	print(555)
	print(777)
	yield 999  # 6

ret = func()
ret.__next__()   # 123 888       或者    print(ret.__next__())   # 123  888  666
ret.__next__()   # 444 555 777    或者   print(ret.__next__())   # 444 555 777  999

ret.__next__()   输出:开始 1 到 yield 之前 (也就是:1,2,...)
print(ret.__next__())   输出:开始 1 到 yield  (也就是:1,2,...,yield )
		# 可以分段输出!

def func():
	print(444)
	return 6
	print(999)  # 遇到 return ,就会跳过!!无法输出 999

def func():
	print(444)
	yield 6
	print(999)  # 第二个 ret.__next__() 会输出!!



去工厂定制10000件衣服  # 一次性定制
def order():
	lst = []
	for i in range(10000):
		lst.append(f"衣服{i}")
	return lst

lst = order()
print(lst)

# 优化方案:分批次,减小负担

# 分批次,每次定制50套
def order():
	lst = []
	for i in range(10000):
		lst.append(f"衣服{i}")
		if len(lst) == 50:
			yield lst
			# 下一次拿数据
			lst = []


gen = order()
print(gen.__next__())  # ['衣服0', '衣服1', .....  '衣服48', '衣服49']
print(gen.__next__())  # ['衣服50', '衣服51', ......, '衣服98', '衣服99']
	......




//********************************************  推导式   *************************************************//

"""
推导式:
	简化代码.
	语法:
		列表推导式: [数据 for循环 if判断]
		集合推导式: {数据 for循环 if判断}
		字典推导式: {k:v for循环 if判断}

	不要把推导式妖魔化.
	(数据 for循环 if判断)  -> 不是元组推导式, 根本就没有元组推导式.  这玩意叫生成器表达式

"""

lst = []
for i in range(10):
	lst.append(i)

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


lst = [i for i in range(10)]
print(lst)      # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


# 1. 请创建一个列表[1,3,5,7,9]
lst = [i for i in range(1, 10, 2)]    # [1, 3, 5, 7, 9]


lst = [i for i in range(10) if i % 2 == 1]    # 这也行
print(lst)    # [1, 3, 5, 7, 9]


# 2. 生成50件衣服
lst = [f"衣服{i}" for i in range(50)]
print(lst)     # ['衣服0', '衣服1', .....  '衣服48', '衣服49']


# 3. 将如下列表中所有的英文字母修改成大写
lst1 = ["allen", "tony", "kevin", "sylar"]
lst2 = [item.upper() for item in lst1]
print(lst2)   # ['ALLEN', 'TONY', 'KEVIN', 'SYLAR']


s = {i for i in range(10)}
print(s)   # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}


# 4. 请将下列的列表修改成字典, 要求 索引做为key, 数据作为value
lst = ['赵本山', "潘长江", "高达", "奥特曼"]

dic = {i: lst[i] for i in range(len(lst))}    # k,v   k=i  v=lst[i]
print(dic)




//********************************************  生成器   *************************************************//

gen = [i**2 for i in range(10)]
print(gen)   # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]


gen = (i**2 for i in range(10))
print(gen)   # <generator object <genexpr> at 0x0000024F131C64D0>  生成器
print(gen.__next__())   # 0
print(gen.__next__())   # 1
print(gen.__next__())   # 4


gen = (i**2 for i in range(10))
for item in gen:
	print(item)
	# 输出:0
	# 	   1
	# 	   4
	# 	   9
	#  .......

lst = list(gen)     # 内部有迭代器
print(lst)    # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

s = list("周杰伦")  # list() =>  for  => next()迭代器
print(s)   # ['周', '杰', '伦']

print(list)   # <class 'list'>
print(list("周杰伦"))   # ['周', '杰', '伦']

//***********************************************  匿名函数  ***********************************************//
"""
匿名函数:
	lambda表达式
	语法:
		变量 = lambda 参数,参数2,参数3....: 返回值

"""
def func():
	print(123456)
	return 9999

ret = func()
print(ret)   #9999



def func(a, b):
	return a + b

ret = func(13, 12)
print(ret)    # 25


fn = lambda a, b: a + b
print(fn)     # <function <lambda> at 0x0000018DB52F04A0>
ret = fn(12, 13)
print(ret)    # 25


//***********************************************  内置函数(下)  ***********************************************//

"""
zip: 可以把多个可迭代内容进行合并
sorted: 排序
filter: 筛选
map:    映射
"""
#        0         1       2
lst1 = ["赵本山", "范伟", '苏有朋']
lst2 = [40, 38, 42]
lst3 = ["卖拐", "耳朵大有福", "情深深雨蒙蒙"]

result = []
for i in range(len(lst1)):
	first = lst1[i]
	second = lst2[i]
	third = lst3[i]
	result.append((first, second, third))
print(result)   # [('赵本山', 40, '卖拐'), ('范伟', 38, '耳朵大有福'), ('苏有朋', 42, '情深深雨蒙蒙')]


result = zip(lst1, lst2, lst3)
print(result)   # <zip object at 0x000001EA17F028C0>    迭代器

for item in result:
	print(item)   # [('赵本山', 40, '卖拐'), ('范伟', 38, '耳朵大有福'), ('苏有朋', 42, '情深深雨蒙蒙')]

lst = list(result)
print(lst)   # [('赵本山', 40, '卖拐'), ('范伟', 38, '耳朵大有福'), ('苏有朋', 42, '情深深雨蒙蒙')]


//******************************  locals    globals  ******************************************************//

a = 188
print(locals())  # 此时locals被写在了全局作用域范围内. 此时看到的就是全局作用域中的内容
					# #  ......'func': <function func at 0x0000023C643F04A0>, 'a': 188}

def func():
	a = 336
	print(locals())  # 此时locals放在局部作用域范围, 看到的就是局部作用域的内容
func()

			  # locals  在全局,那就是显示全局内容    如果在 局部,那就是局部



c = 12
print(globals())  # globals看到的是全局作用域中的内容    无论在哪个位置,都是全局
def func():
	a = 336
	print(globals())  #  ......'func': <function func at 0x0000023C643F04A0>, 'i': 55}
func()



//***********************************  sorted ******  reverse  *************************************************//

lst = [16,22,68,1,147,256,49]
s = sorted(lst, reverse=True)  # reverse翻转
print(s)

#       1      3        2       4           123132
lst = ["秋", "张二嘎", "比克", "卡卡罗特", "超级宇宙无敌大帅B"]

# def func(item):  # item对应的就是列表中的每一项数据
#     return len(item)

s = sorted(lst, key=lambda x: len(x))
print(s)



lst = [
	{"id": 1, "name": "周润发", "age": 18, "salary": 5200},
	{"id": 2, "name": "周星驰", "age": 28, "salary": 511100},
	{"id": 3, "name": "周海媚", "age": 78, "salary": 561230},
	{"id": 4, "name": "周伯通", "age": 12, "salary": 532100},
	{"id": 5, "name": "周大兴", "age": 35, "salary": 53210},
	{"id": 6, "name": "周周有辣", "age": 47, "salary": 520},
	{"id": 7, "name": "周扒皮", "age": 8, "salary": 12},
]

# 1.根据每个人的年龄排序
s = sorted(lst, key=lambda d: d['age'])     # 默认:reverse=False  不会反转
print(s)     # 按照年龄,升序

# 2.根据工资进行排序. 从大到小
s = sorted(lst, key=lambda d: d['salary'], reverse=True)
print(s)     # 按照工资,降序


//*****************************************  filter ****************************************************//


#        T         T     T         F            F
lst = ["张无忌", "张三丰", "张翠山", "灭绝小师太", "小狐仙"]
f = filter(lambda x: x.startswith("张"), lst)        #  x.startswith("张")  等价于 x[0]=='张'
print(list(f))



lst = [1,2,3,4,5,6,7,8,9]

result = [item * item for item in lst]
print(result)   # [1, 4, 9, 16, 25, 36, 49, 64, 81]

r = map(lambda x: x * x, lst)
print(list(r))    # [1, 4, 9, 16, 25, 36, 49, 64, 81]

//**************************************  递归  *************************************************************//

"""
递归:  函数自己调用自己

递归如果没有任何东西拦截的话. 它默认就是一个死循环
python默认是有递归深度的限制的. 默认的最大递归深度是1000
"""

def func():
	print(123)
	func()

func()

import sys

print(sys.getrecursionlimit())   # 1000   默认的递归深度

sys.setrecursionlimit(2000)

def xxxx(a, b, c):

	xxxxxx

	return xxxx


				 2023.12.19  18:36   拿下python基础!!开始冲向爬虫!!
							非常的期待~~~~

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值