当前位置:
首页 > temp > python入门教程 >
-
python--高级语法 6
day11:
1、补充:默认参数的陷阱
-
陷阱只针对于默认参数是可变的数据类型:
- 结论:如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。
# 陷阱只针对于默认参数是可变的数据类型:
def func(name,alist=[]):
alist.append(name)
return alist
ret1=func("mike")
print(ret1,id(ret1)) #打印结果 ['mike']
ret2=func('太白金星')
print(ret2,id(ret2))
['mike'] 2579283148744
['mike', '太白金星'] 2579283148744
Process finished with exit code 0
- 图形讲解
面试题1:
def func(a,list=[]):
list.append(a)
return list
print(func(10))
print(func(20,[]))
print(func(100))
[10]
[20]
[10, 100]
Process finished with exit code 0
#等同于如下:
l1 = []
l1.append(10)
print(l1)
l2 = []
l2.append(20)
print(l2)
l1.append(100)
print(l1)
面试题2:
- 面试题2是 3个执行完才打印,面试题1是执行一个打印一次
def func(a,list=[]):
list.append(a)
return list
ret1=func(10)
ret2=(func(20,[]))
ret3=(func(100))
print(ret1)
print(ret2)
print(ret3)
[10, 100]
[20]
[10, 100]
Process finished with exit code 0
2、补充:局部作用域的坑:
global:
1, 在局部作用域声明一个全局变量。
注意:要先调用函数,这样函数里的全局变量才可以被引用
#global
#1, 在局部作用域声明一个全局变量。
name = 'alex'
def func():
global name
name = '太白金星'
print(name)
func()
print(name)
太白金星
太白金星
Process finished with exit code 0
- 如果先调用局部变量中的全局变量,会报错-----要先调用函数
def func():
global name
name = '太白金星'
print(name)
print(name)
func()
NameError: name 'name' is not defined
Process finished with exit code 1
2.修改一个全局变量
- 原来这样写会报错
- 加入global 就可以完成引用全局变量并且修改全局变量
#2. 修改一个全局变量
count=1
def func():
global count
count=count+1
print(count)
func()
print(count)
1
2
Process finished with exit code 0
nonlocal
1.不能够操作全局变量
count = 1
def func():
nonlocal count
count += 1
func()
SyntaxError: no binding for nonlocal 'count' found
Process finished with exit code 1
2.局部作用域:内层函数对外层函数的局部变量进行修改
# 2. 局部作用域:内层函数对外层函数的局部变量进行修改。
def wrapper():
count = 1
def inner():
nonlocal count
count += 1
print(count)
inner()
print(count)
wrapper()
3、函数名的运用
1.函数名指向的是函数的内存地址。
函数名 + ()就可以执行次函数。
def func():
print(666)
func()
# 1. 函数名指向的是函数的内存地址。
# 函数名 + ()就可以执行次函数。
print(func,type(func))
666
<function func at 0x0000022029A21E18> <class 'function'>
Process finished with exit code 0
2, 函数名就是变量。
def func():
print(666)
f=func
f1=f
f2=f1
f2()
666
Process finished with exit code 0
- 图形解释
def func():
print('in func')
def func1():
print('in fun1')
func1=func
func1()
#打印那个结果?
#分析:类比如下
a=1
b=2
a=b
print(a)
in func
2
Process finished with exit code 0
3.函数名可以作为容器类数据类型的元素
# 3. 函数名可以作为容器类数据类型的元素
# a = 1
# b = 2
# c = 3
# l1 = [a,b,c]
# print(l1)
def func1():
print('in fun1')
def func2():
print('in fun2')
def func3():
print('in fun3')
a1=[func1,func2,func3]
for i in a1:
i()
in fun1
in fun2
in fun3
Process finished with exit code 0
4.函数名可以作为函数的参数
def func():
print('in func')
def fun1(x):
x() #相当于func()
print('in func1')
fun1(func)
in func
in func1
Process finished with exit code 0
5.函数名可以作为函数的返回值
# 5. 函数名可以作为函数的返回值
def func():
print('in func')
def func1(x):
print('in func1')
return x
ret=func1(func)
ret()
in func1
in func
Process finished with exit code 0
4、新特性:格式化输出
1.旧的格式化方式
%s 和 format
#旧个格式化输出,太麻烦了
name = '太白'
age = 18
msg = '我叫%s,今年%s' %(name,age)
print(msg)
msg1 = '我叫{},今年{}'.format(name,age)
print(msg)
我叫太白,今年18
我叫太白,今年18
Process finished with exit code 0
2.新特性:格式化输出
# 新特性:格式化输出
name = '太白'
age = 18
msg = f'我叫{name},今年{age}'
print(msg)
我叫太白,今年18
Process finished with exit code 0
2.1 可以加表达式
# 可以加表达式
dic = {'name':'alex','age': 73}
msg = f'我叫{dic["name"]},今年{dic["age"]}'
print(msg)
count = 7
print(f'最终结果:{count**2}')
name = 'barry'
msg = f'我的名字是{name.upper()}'
print(msg)
最终结果:49
我的名字是BARRY
Process finished with exit code 0
2.2 结合函数写
# 结合函数写:
def _sum(a,b):
return a + b
msg = f'最终的结果是:{_sum(10,20)}'
print(msg)
# ! , : { } ;这些标点不能出现在{} 这里面。
最终的结果是:30
Process finished with exit code 0
优点:
-
结构更加简化。
-
可以结合表达式,函数进行使用。
-
效率提升很多。
5、迭代器:(重点)
1.可迭代对象
-
字面意思:对象?python中一切皆对象。一个实实在在存在的值,对象。
可迭代?:更新迭代。重复的,循环的一个过程,更新迭代每次都有新的内容,
可以进行循环更新的一个实实在在值。
专业角度:可迭代对象? 内部含有
'__iter__'
方法的对象,可迭代对象。目前学过的可迭代对象?str list tuple dict set range 文件句柄
-
获取对象的所有方法并且以字符串的形式放在列表里
语法:dir()
-
判断一个对象是否是可迭代对象
-
用dir()获取所有方法,如果内部含有
'__iter__'
方法,就是可迭代对象
-
用dir()获取所有方法,如果内部含有
#获取对象的所有方法
# s1 = 'fjdskl'
# print(dir(s1))
l1=[1,2,3]
print(dir(l1))
print('__iter__' in dir(l1)) #打印结果True 就表示可迭代对象
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
True
Process finished with exit code 0
-
小结
-
字面意思:可以进行循环更新的一个实实在在值。
-
专业角度: 内部含有
'__iter__'
方法的对象,可迭代对象。 -
判断一个对象是不是可迭代对象:
'__iter__'
in dir(对象) -
str list tuple dict set range
-
优点:
- 存储的数据直接能显示,比较直观。
- 拥有的方法比较多,操作方便。
-
缺点:
-
占用内存。
-
不能直接通过for循环,不能直接取值(索引,key)。
-
-
2.迭代器的定义
- 字面意思:更新迭代,器:工具:可更新迭代的工具。
-
专业角度:内部含有
'__iter__'
方法并且含有'__next__'
方法的对象就是迭代器。 -
可以判断是否是迭代器:
'__iter__'
and'__next__'
在不在dir(对象)
3.判断一个对象是否是迭代器
#判断文件是否是迭代器
with open('文件1',encoding='utf-8',mode='w') as f1:
print(('__iter__' in dir(f1)) and ('__next__' in dir(f1)))
s1 = 'fjdag'
print('__next__' in dir(s1))
True
False
Process finished with exit code 0
4.可迭代对象如何转化成迭代器
`iter([1,2,3])`
#或者
s1.__iter__()
s1 = 'fjdag'
obj=iter(s1)
#s1.__iter__()
print(obj)
print('__next__' in dir(obj))
<str_iterator object at 0x0000029B94D1A278>
True
Process finished with exit code 0
5.迭代器的取值
-
一个next 取一个值
-
多一个next 就会报错
s1 = 'python'
obj=iter(s1)
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
p
y
t
h
o
n
Process finished with exit code 0
- 报错结果
Traceback (most recent call last):
File "D:/PycharmProjects/zixue_python/day_01/12_迭代器.py", line 25, in <module>
print(next(obj))
StopIteration
6.要迭代器有什么用?
- 当数据很大的时候,我要考虑把这些大批量数据存储起来,需要节省内存,所以要考虑迭代器
-
节省内存。
-
自己理解如何节省内存:比如定义一个列表,那根据内存机制,内置中会保存这个列表中所有数据,然后分配内存地址(即id)
如果把这个列表转换为迭代器,这时候next一次,取一个值,然后存储这个值
-
-
惰性机制,next一次,取一个值。
7.while循环模拟for循环机制
l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652]
# 将可迭代对象转化成迭代器。
obj = iter(l1)
while 1:
try:
print(next(obj))
except StopIteration:
break
8.可迭代对象与迭代器的对比
- 可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8G内存是可以承受的)的一个数据集。
- 当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
- 是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
- 当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
出处:https://www.cnblogs.com/wushaofan/p/17156647.html
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数