VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 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

优点:

  1. 结构更加简化。

  2. 可以结合表达式,函数进行使用。

  3. 效率提升很多。

5、迭代器:(重点)

1.可迭代对象

  • 字面意思:对象?python中一切皆对象。一个实实在在存在的值,对象。

    可迭代?:更新迭代。重复的,循环的一个过程,更新迭代每次都有新的内容,

    可以进行循环更新的一个实实在在值。

    专业角度:可迭代对象? 内部含有'__iter__'方法的对象,可迭代对象。

    目前学过的可迭代对象?str list tuple dict set range 文件句柄

  • 获取对象的所有方法并且以字符串的形式放在列表里

语法:dir()
  • 判断一个对象是否是可迭代对象
    • 用dir()获取所有方法,如果内部含有'__iter__'方法,就是可迭代对象
#获取对象的所有方法

# 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

    • 优点:

      1. 存储的数据直接能显示,比较直观。
      2. 拥有的方法比较多,操作方便。
    • 缺点:

      1. 占用内存。

      2. 不能直接通过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.要迭代器有什么用?

  • 当数据很大的时候,我要考虑把这些大批量数据存储起来,需要节省内存,所以要考虑迭代器
  1. 节省内存。

    • 自己理解如何节省内存:比如定义一个列表,那根据内存机制,内置中会保存这个列表中所有数据,然后分配内存地址(即id)

      如果把这个列表转换为迭代器,这时候next一次,取一个值,然后存储这个值

  2. 惰性机制,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

相关教程