python 第四天

第一、

1、函数的嵌套的调用:在调用函数的过程中又调用了其他的函数。代码简洁、可读性较高。

例1:

def foo():

print(‘from foo‘)

def bar():

print(‘from bar‘)

foo()

bar()

#结果:

from bar

from foo

例2:

def max2(x,y):

if x > y:

return x

else:

return y

def max4(a,b,c,d):

res1 = max2(a,b)

res2 = max2(res1,c)

res4 = max2(res2,d)

return res4

print(max4(1,4,2,5))

2、函数的嵌套定义:在一个函数的内部、又定义另外一个函数。

第二、

1、名称空间:存放名字的地方、准确的说是存放名字和变量值绑定关系的地方。

python中的名称空间有:

1、内置名称空间:在py启动的时候产生、存放一些python自带的名字。

print(),len(),max()……

2、全局名称空间:在执行文件时、文件级别定义的名字。

x=1、

3、局部名称空间:在执行文件的过程中、如果调用了函数、则会产生该函数的局部名称空间、用来存放该函数内定义的名字。在函数调用时生效,函数调用结束后失效。

三个名称空间的加载顺序:

内置-->全局-->局部

从上到下。

三个名称空间的查询顺序:

局部-->全局-->内置

从下往上。

2、作用域:作用的应用范围

全局作用域:全局有效、任何位置都能访问得到。

全局包含:globals

1、内置名称

2、全局名称

例:

def f1():

def f2():

def f3():

print(max)

f3()

f2()

f1()

<built-in function max>

局部作用域:临时有效、局部有效。

局部包含:locals

1、局部名称

全局作用域的局部依然是全局作用域。

dir 查看对象下有哪些方法。

#global 关键字

global

x=1

def f1():

global x

x=2

f1()

print(x)

2

#不加global 也可以修改可变类型的数据

l = []

def f2():

l.append(‘f2‘)

f2()

print(l)l = []

def f2():

l.append(‘f2‘)

f2()

print(l)

[‘f2‘]

x=0

def f1():

x=3

def f2():

x=2

def  f3():

global x

x=3

f3()

f2()

f1()

print(x)

3

x=0

def f1():

x=3

def f2():

x=2

def  f3():

global x

x=3

f3()

print(x)

f2()

f1()

2

x=0

def f1():

x=3

def f2():

x=2

def  f3():

nonlocal x

x=3

f3()

print(x)

f2()

f1()

3

#优先掌握:作用域关系在函数定义时就已经定义了,与调用的位置无关。需要回到原来定义函数的位置去找作用域关系

x= 1

def f1():

def f2():

print(x)

return f2

def foo(func):

x=100

func()

foo(f1())

1

#此处值为1是因为作用域的定义在上面。

3、闭包函数:闭合、包裹。

定义:

1、定义在函数内部的函数

2、包含对外部作用域名字的引用,而不是全局作用域名字得引用,那么该内部函数就称为闭包函数。

def f1():

x=2

def f2():

print(x)

return f2

res=f1()

res()

2

#此处的f2函数就是闭包函数、此时他不是独立存在的他的外围包一层作用域。

def deco():

x=123123

def wrapper():

print(x)

return wrapper

wrapper()

func=deco()

func()

123123

#查看外部变量

import requests

def index(url):

def get():

print(requests.get(url).text)

return get

python_web=index(‘http://www.python.org‘)

baidu_web=index(‘http://www.baidu.com‘)

print(python_web.__closure__)

(<cell at 0x0000007E65EA55E8: str object at 0x0000007E66035DF8>,)

import requests

def index(url):

def get():

print(requests.get(url).text)

return get

python_web=index(‘http://www.python.org‘)

baidu_web=index(‘http://www.baidu.com‘)

print(python_web.__closure__[0].cell_contents)

http://www.python.org

当闭包内部函数没有被作用域包住的时候,他的作用域为None

4、为什么要用装饰器?

1、开发封闭原则:对扩展是开放的、对修改是封闭的。

装饰器:目的为其他人添加新功能、

装饰器可以是任意可调用对象、被装饰的对象可以是任意可调用对象。

2、装饰器需要遵循的原则:

2.1 不修改装饰对象的源代码

2.2 不修改被调用对象的功能

其目的就是满足1和2条件添加新功能

例1:

import time

def index():

time.sleep(3)

print(‘welcome to index‘)

def home():

time.sleep(3)

print(‘welcome to home‘)

def timmer(func):

def wrapper():

start=time.time()

func()

stop=time.time()

print(‘run time is %s‘ %(stop-start))

return wrapper

index=timmer(index)

home=timmer(home)

index()

home()

简写装饰器:

import time

def timmer(func):

def wrapper():

start=time.time()

func()

stop=time.time()

print(‘run time is %s‘ %(stop-start))

return wrapper

@timmer #装饰器需要在调用的上面

def index():

time.sleep(3)

print(‘welcome to index‘)

@timmer #@等价 home=timmer(home)

def home():

time.sleep(3)

print(‘welcome to home‘)

index()

home()

#@装饰器名、必须写在被装饰对象的正上方、而且是单独一行

例2:、对被修饰对象加参数

import time

def timmer(func):

def wrepper(*args,**kwargs):

start=time.time()

func(*args,**kwargs)

stop=time.time()

print(‘run time is %s‘ %(stop-start))

return wrepper

@timmer

def index():

time.sleep(2)

print(‘welcome to index‘)

@timmer

def home(name):

time.sleep(2)

print(‘welcome to %s‘ %name)

index()

home(‘home‘)

例3:返回值

#对被修饰对象加参数

import time

def timmer(func):

def wrepper(*args,**kwargs):

start=time.time()

res=func(*args,**kwargs)

stop=time.time()

print(‘run time is %s‘ %(stop-start))

return res

return wrepper

@timmer

def index():

time.sleep(2)

print(‘welcome to index‘)

return  123

@timmer

def home(name):

time.sleep(2)

print(‘welcome to %s‘ %name)

return 456

res=index()

print(res)

res1=home(‘home‘)

print(res1)

>>

welcome to index

run time is 2.00014328956604

123

welcome to home

run time is 2.0002007484436035

456

例3:用装饰器实现用户登录认证的功能

cust_dic={‘user‘:None}

def auth(func):

def auth_toke(*args,**kwargs):

if cust_dic[‘user‘]:

return func(*args, **kwargs)

user_inp = input(‘user>> ‘).strip()

pass_inp = input(‘pass>> ‘).strip()

with open(‘db‘,‘r‘,encoding=‘utf-8‘) as use_f:

use_list=eval(use_f.read())

if user_inp == use_list[0][‘user‘] and pass_inp == use_list[0][‘password‘]:

cust_dic[‘user‘] = user_inp

return func(*args,**kwargs)

else:

print(‘log in error‘)

return auth_toke

@auth

def access():

print(‘login sessfull‘)

@auth

def error(name):

print(‘welcome to is %s‘ %name)

access()

error(‘json‘)

>>:

user>> json

pass>> 123123

login sessfull

welcome to is json

#闭包函数只需要用到3层就能满足一切函数的传参。

#装饰器补充

import time

def foo():

‘‘‘这是index函数‘‘‘

time.time()

print(‘access‘)

return 123

# print(help(foo))

print(foo.__doc__)

这是index函数

#多个装饰器

谁在上面谁先生效。

5、迭代器:

迭代:重复的过程、每一次重复都是基于上一次的结果而来。

取出序列类型的元素就是迭代

例1:

l = [‘a‘,‘b‘,‘c‘,‘d‘]

count=0

while  count < len(l):

print(l[count])

count+=1

>>

a

b

c

d

5.1、迭代器:取出非序列数据、不按索引。

5.2、可迭代对象:凡是对象有__iter__方法:对象.__iter__,该对象就是可迭代对象。

可迭代对象有:字符串、列表、元组、字典。

例2:

dic={‘name‘:‘egon‘}

res=dic.__iter__()

print(res)  #iterator 迭代器

例3:

dic={‘name‘:‘egon‘,‘age‘:11}

res=dic.__iter__()

print(next(res))

print(next(res)

>>

name

age

#StopIteration 提示迭代器没有值了,应该停止了

迭代器本身也是可迭代的对象。

dic={‘name‘:‘egon‘,‘age‘:11}

# res=dic.__iter__()

res=iter(dic)

print(next(res))

print(next(res))

>>

name

age

#当迭代器遇到stopiteration的时候会停止运行。

s=‘hello‘

l=[‘a‘,‘b‘,‘c‘,‘d‘]

iter_l=iter(l)

while True:

try:

print(next(iter_l))

except StopIteration:

break

>>

a

b

c

d

6、迭代器对象:

6.1、有__iter__,执行结果仍然是迭代器本身

6.2、有__next__,执行一次取一个值

迭代器对象的优点:

1、提供统一的(不依赖于索引的)迭代方式

2、迭代器本身、比其他数据类型更省内存

3、迭代器可以存放无穷无尽个值。

例1、

with open(‘db‘,encoding=‘utf-8‘) as f:

print(next(f))

print(next(f))

print(next(f))

print(next(f))

>>

111111111111111111111

11111111111111

11111111111

1111111

迭代器缺点:

1、一次性的、只能往后不能回退、不如索引取值更灵活。

占内存大的环境不能用索引方式。

2、无法预知什么时候结束、即无法预知长度。

for循环就是一个迭代器。

for循环的对象就是可迭代对象。

判断一个对象是否是可迭代对象的方法就是?看该对象是否有iter方法。

文件是迭代器。****

7、生成器

生成器:在函数内部包含yield关键字、那么该函数的执行结果是生成器

生成器就是迭代器。

#yield的功能:

1、把函数的结果做生成器(以一种优雅的方式封装__iter__,__next__)

2、函数暂停与继续运行的状态是由yield

例1、手动实现rang函数。

def my_rang(start,stop):

while True:

if start == stop:

raise StopIteration

yield start

start+=1

for i in my_rang(1,3):

print(i)

7.1、yield 与 return的比较?

相同:都有返回值的功能

不同:return只能返回一次、

例2、taif -f |grep 实现

import time

def tail(filepath):

with open(filepath,‘r‘) as f:

f.seek(0,2)

while True:

line = f.readline()

if line:

yield line

else:

time.sleep(0.2)

def grep(patten,lines):

for line in lines:

if patten in line:

print(line,end=‘‘)

grep(‘error‘,tail(‘db‘))

8、三元表达式:

为真时的结果 if 判定条件 else 为假时的结果

1 if 5>3 else 0

输出为1、如果5大于3、否则输出0

9、列表解析

根据已有列表,高效创建新列表的方式。

列表解析是Python迭代机制的一种应用,它常用于实现创建新的列表,因此用在[]中。

例1:传统方式

l=[]

for n in range(11):

l.append(n)

print(l)

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

例2:列表解析

l=[ n for n in range(10)]

print(l)

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

例3:取出10内大于4的数字

传统方法:

l=[]

for n in range(10):

if n >= 4:

l.append(n)

print(l)

[4, 5, 6, 7, 8, 9]

列表解析:

l=[ n for n in range(10) if n >=4 ]

print(l)

[4, 5, 6, 7, 8, 9]

10、生成器表达式:

生成器表达式并不真正的创建数字列表,而是返回一个生成器对象,此对象在每次计算出一个条目后,把这个条目"产生"(yield)出来。生成器表达式使用了"惰性计算"或称作"延时求值"的机制。

序列过长,并且每次只需要获取一个元素时,应该考虑生成器表达式而不是列表解析。

N=(i**2 for i in range(11))

print(N)

<generator object <genexpr> at 0x000000A5BE8A1D00> #此处返回的是一个生成器的地址

生成器取值通过next方法:

N=(i**2 for i in range(11))

# print(N)

print(next(N))

print(next(N))

print(next(N))

print(next(N))

0

1

4

9

生成器取值到元素遍历完毕之后,抛出StopIteration

N=(i**2 for i in range(11))

# print(N)

while True:

try:

print(next(N))

except StopIteration:

break

时间: 2024-10-14 22:56:10

python 第四天的相关文章

Python 基础 四

今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 在Python中四个产生反射的函数,分别是:hasattr();getattr();setattr();delattr(); 下列方法适用于类和对象(一切皆对象,类本身也是一个对象) hasattr((object, name, default=None)) 判断object中有没有一个name

Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 先定义一个基本的装饰器: ########## 基本装饰器 ########## def orter(func):    #定义装饰器     de

怒学Python——第四篇——函数与模块

Python的函数:其实和C++非常类似,不过由于是弱类型的语言(用起来感觉是......),把那些类型声明都去掉了,传的是值不是引用(至少2.7是),有一点点小区别是前面必须加def来定义(好像宏定义的样子......),下面给出示例 def sum(a, b): #sum为函数名,注意冒号...... c = a + b #这一部分是函数的语句块 return c #到这里函数就结束了,和C++一样 print sum(1, 2) #根据函数名调用函数,输出1+2的值 这里也有lambda函

selenium-webdriver(python) (十四) -- webdriver原理(转载虫师自动化)

selenium-webdriver(python) (十四) -- webdriver原理 2013-08-22 12:55 by 虫师, 13926 阅读, 12 评论, 收藏, 编辑 之前看乙醇视频中提到,selenium 的ruby 实现有一个小后门,在代码中加上$DEBUG=1 ,再运行脚本的过程中,就可以看到客户端请求的信息与服务器端返回的数据:觉得这个功能很强大,可以帮助理解webdriver的运行原理. 后来查了半天,python并没有提供这样一个方便的后门,不过我们可以通过代理

初学Python(四)——set

初学Python(四)——set 初学Python,主要整理一些学习到的知识点,这次是set. # -*- coding:utf-8 -*- #先来看数组和set的差别 d=[1,1,2,3,4,5] s = set([1,1,2,3,4,5]) print d print s ''''' 打印出来的效果看出,多了一个set()后, list就变成了不能存储重复数据的类型了, 这叫set,不是list. ''' #添加元素 s.add(6) print s #删除元素 s.remove(6) p

Python进阶(四十)-数据可视化の使用matplotlib进行绘图

Python进阶(四十)-数据可视化の使用matplotlib进行绘图 前言 ??matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包.我将在这篇文章中介绍matplotlib API的核心对象,并介绍如何使用这些对象来实现绘图.实际上,matplotlib的对象体系严谨而有趣,为使用者提供了巨大的发挥空间.用户在熟悉了核心对象之后,可以轻易的定制图像.matplotlib的对象体系也是计算机图形学的一个优秀范例.即使你不是Python程序员,你也可以从文中

Python第四课(数据类型)

Python第四课(数据类型)   >>>转到思维导图>>>转到我的博客 整型(int) 用途:记录QQ号.手机号.身份证号等 定义:age = 18 常用操作+内置的方法 ?int只能转存数字的字符串,小数点都不行 ?进制转换 >>> print(int('1100',2)) # 二进制转十进制 0,1 12 >>> print(int('14',8)) # 八进制转十进制 0-7 12 >>> print(int

Python进阶(四十九)-初识Flask Blueprint

Python进阶(四十九)-初识Flask Blueprint 前言   在进行Python Web开发时选择Flask框架.项目模块划分阶段,使用Blueprint(这里暂且称之为“蓝本”).Blueprint通过把实现不同功能的module分开,从而把一个大的application分割成各自实现不同功能的module.在一个Blueprint中可以调用另一个blueprint的view function, 但要加相应的blueprint名.   Blueprint还有其他好处,其本质上来说就

python基础四

递归调用.高阶函数.函数作用域.python内置函数.装饰器.模块.random.json串和积累 一.递归调用 递归调用就是一个函数自己调用自己,自我调用最多调用999次. 特性:1.必须有一个明确的结束条件: 2.每次进入更深一层递归时,问题规模相比上次递归都应该有所减少: 3.递归效率不高,建议少用递归 def test(): n=int(input('please input a number: ')) if n%2==0: return True print('输入的不是偶数') te

python 正则表达式 四例

本文转自 http://www.cnblogs.com/kaituorensheng/p/3489492.html 阅读目录 一. 判断字符串是否是全部小写 二.  首字母缩写词扩充 三. 去掉数字中的逗号 四. 中文处理之年份转换(例如:一九四九年--->1949年) 会用到的语法 正则字符 释义 举例 + 前面元素至少出现一次 ab+:ab.abbbb 等 * 前面元素出现0次或多次 ab*:a.ab.abb 等 ? 匹配前面的一次或0次 Ab?: A.Ab 等 ^ 作为开始标记 ^a:ab