python3 函数 二

1、函数嵌套

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

def f1():
    x=1
    def f2():
        print(‘from f2‘)
    f2()
f1()

1、2函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数。

def bar():

print(‘from bar‘)

def foo():
    print(‘from foo‘)
    bar()
foo()

通过函数的嵌套使用,分解成操作减少重复代码,一次调用。

2、名称空间与作用域

名称空间

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

2、2内置名称空间:python自带的名字,在python解释器启动时产生,存放一些python内置的名字

2、3全局名称空间:在执行文件时,存放文件级别定义的名字,Python中顶行写的。

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

2、5加载顺序:内置名称空间------>全局名称空间----->局部名称空间

2、6名字的查找顺序:局部名称空间------>全局名称空间----->内置名称空间

作用域,作用的范围

全局作用域:全局存活,全局有效

局部作用域:局部存活,局部有效

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。

def f1():

x
= 1

y
= 2

print(locals())

print(globals())

f1()

print(locals())

print(globals())

print(locals() is globals())

修改全局变量的值

x=1

def f1():

global x

x=2

f1()

print(x)

修改局部变量的值

x = 0

def f1():

x = 1

def f2():

x = 2

def f3():

nonlocal x  #改的是函数正上方的值

x = 3

f3()

f2()

f1()

优先掌握:作用域关系,在函数定义时就已经固定
,于调用位置无关,在调用函数时,必须回到函数原来定义的位置去找作用域关系.

x = 1

def f1():

def f2():

print(x)

return f2 x = 1

def f1():

def f2():

print(x)

return f2

func = f1()

func()

func = f1()

func()

查看作用域:globals(),locals()

global

nonlocal

LEGB 代表名字查找顺序: locals -> enclosing function
-> globals -> __builtins__

locals 是函数内的名字空间,包括局部变量和形参

enclosing 外部嵌套函数的名字空间(闭包中常见)

globals 全局变量,函数定义所在模块的名字空间

builtins 内置模块的名字空间

3、闭包函数

3、1 闭包函数:
定义在函数内部的函数

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

import requests

def
deco(url):

def wrapper():

return (requests.get(url).text)

return wrapper

get =
deco(‘https://www.baidu.com‘)

print(get())

闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

4、装饰器

开放封闭原则:对拓展是开放的,对修改是封闭的

装饰器:装饰他人的工具,装饰的目的是为他人添加新功能

装饰器本身是任意可调用对象,被装饰的对象本身也可以是任意可调用的对象

装饰器遵循的原则:1、不修改被装饰对象的源代码

         2、不修改被调用对象的调用方式

装饰器的目的:在遵循1和2原则的前提下,为其他函数添加新功能

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

示例:

import time

def timmer(func):

def wrapper(*args,**kwargs):

start_time=time.time()

res=func(*args,**kwargs)

stop_time=time.time()

print(‘run time is %s‘
%(stop_time-start_time))

return res

return wrapper

@timmer

def foo():

time.sleep(3)

print(‘from foo‘)

foo()

装饰器语法:

被装饰函数的正上方,单独一行

@deco1

@deco2

@deco3

def foo():

pass

foo=deco1(deco2(deco3(foo)))

装饰器补充:wraps

from functools import wraps

def deco(func):

@wraps(func) #加在最内层函数正上方

def wrapper(*args,**kwargs):

return func(*args,**kwargs)

return wrapper

@deco

def index():

‘‘‘去你妹的‘‘‘

print(‘from index‘)

print(index.__doc__)

5、迭代器

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

s=‘hello‘

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

t=(‘a‘,‘b‘,‘c‘,‘d‘)

dic={‘name‘:‘egon‘,‘sex‘:‘m‘,"age":18}

set1={1,2,3}

f=open(‘db.txt‘)

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

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

dic={‘name‘:‘egon‘,‘sex‘:‘m‘,"age":18}

iter_l=iter(l)

iter_dic=iter(dic)

while True:

try:

k=next(iter_dic)

print(k,dic[k])

except StopIteration:

break

可迭代对象:

1 有__iter__,执行得到仍然是迭代本身

2 有__next__

迭代器对象的优点

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

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

迭代器对象的缺点

1、一次性,只能往后走,不能回退,不如索引取值灵活

2、无法预知什么时候取值结束,即无法预知长度

判断可迭代对象与迭代器对象

print(isinstance(s,Iterable))    判断s数据类型是否是可迭代对象

print(isinstance(s,Iterator))    只有文件是迭代器对象

6、生成器

生成器:

在函数内部包含yield关键字,那么该函数执行的结果就是生成器(生成器就是迭代器)

def
func():

print(‘first‘)

yield 11111111

print(‘second‘)

yield 2222222

print(‘third‘)

yield 33333333

print(‘fourth‘)

g=func()

print(g)

from
collections import Iterator

print(isinstance(g,Iterator))

yield的功能:

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

2 函数暂停与再继续运行的状态是由yield,保存当前运行状态。

def func(n):

while True:

yield n

n+=1

g=func(0)

print(next(g))

def my_range(start,stop):

while True:

if start == stop:

raise StopIteration

else:

yield start

start+=1

g=my_range(1,3)

for i in my_range(1,3):

print(i)

yield与return的比较?

相同:都有返回值的功能

不同:return只能返回一次值,而yield可以返回多次值

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(pattern,lines):

for line in lines:

if pattern in line:

print(line,end=‘‘)

grep(‘error‘,tail(‘access.log‘))

7、三元表达式,列表推导式,生成器表达式

三元表达式

x=10

res=x if x > 3 else ‘no‘

print(res)

列表解析

l = [‘egg%s‘%i for i in range(10)]

l=[‘egg%s‘ %i for i in range(10)  if i >=5]

print(l)

names =
[‘alex_sb‘,‘egon‘,‘wupeiqi_sb‘,‘yuanhao_sb‘]

names_new = [name for name in names if
name.endswith(‘sb‘)]

print(names_new)

生成器表达式

g = (‘egg%s‘%i for i in range(10))  # 将中括号变成小括号即为生成器表达式

# 迭代器同一时间在内存中只有一个值

print(g)

print(next(g))

print(next(g))

with open(‘a.txt‘,encoding=‘utf-8‘) as f:

g=(len(line) for line in f)

print(max(g))

时间: 2024-10-05 04:58:37

python3 函数 二的相关文章

python3基础二——基本的数据类型二

一.数字(Number) 1.Python支持三种不同的数值类型:整型(int),浮点型(float),复数(complex) 2.Python数字数据类型用于存储数值 3.数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间 4.可以通过使用del语句删除数字对象.单个或多个对象的引用 5.数学常量:pi(圆周率).e(自然常数) 6.Python数字类型转换int() .float(). complex() 7.浮点数也就是小数,浮点数没有大小限制,但是超出一定范围

Python3快速入门(五)——Python3函数

Python3快速入门(五)--Python3函数 一.函数定义 1.函数定义 Python 定义函数使用 def 关键字,一般格式如下: def function_name(parameter_list): pass 默认情况下,参数值和参数名称按函数声明中定义的顺序进行匹配.函数代码块以?def?关键词开头,后接函数标识符名称和圆括号?().任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数.函数的第一行语句可以选择性地使用文档字符串描述函数说明.函数内容以冒号起始,并且进行

学习13.内容# 1.内置函数二 # 2.闭包

目录 内置函数二 重要的内置函数和匿名函数 闭包 内置函数二 abs 绝对值 返回的都是正数 print([abd(i) for i in lst]) enumerate 枚举 ("可迭代对象","序号的起始值") 默认起始值是0 [(0,1),(1,2),(2,3)] print([i for i in enumerate(lst,10)]) lst = [11,22,33,-44,23,21] new_lst = [] for i in enumerate(ls

内置函数(二) 闭包

内置函数(二) 内置函数 1.abs( ) print([abs(i) for i in lst]) # 绝对值 -- 返回的都是正数 2.enumerate( ) [(0,1)(1,2)(2,3)] print([i for i in enumerate(lst,10)]) # 枚举("可迭代对象","序号的起始值") 默认的起始值是 0 3.max( ) print(max([1,2,3,4,56,7,8])) # 求最大值 print(max([1,2,-33

python015 Python3 函数

Python3 函数函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函数,这被叫做用户自定义函数. 定义一个函数你可以定义一个由自己想要功能的函数,以下是简单的规则:函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ().任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数.函数的第一行语句可以选择性地使用文档字符串-用于存放函数

python3 -> 函数注释 Function Annotations

Python 3.X新增加了一个特性(Feature),叫作函数注释 Function Annotations 它的用途虽然不是语法级别的硬性要求,但是顾名思义,它可做为函数额外的注释来用. Python中普通的函数定义如下: def func(a, b, c): return a + b + c >>> func(1, 2, 3) 6 添加了函数注释的函数会变成如下形式: def func(a: 'spam', b: (1, 10), c: float) -> int: retu

C#中的函数(二) 有参有返回值的函数

接上一篇 C#中的函数(-) 无参无返回值的函数 http://www.cnblogs.com/fzxiaoyi/p/8502613.html 这次研究下C#中的函数(二) 有参有返回值的函数 依然写一个小例子,用来测试 跟上一个例子差不多,区别就是MyFunction有二个参数a,b,返回二个数相加的值 F5调试运行,中断后转到反汇编 这里很明显看到不同了 这里就得讲到参数传递的方式,参数从左向右依次存入寄存器ecx edx 但是不同的编程语言有不同的传递参数的方式,有空再写一篇文章介绍下 要

0046-简单的分段函数(二)

简单的分段函数(二) 难度级别:A: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 已知下列分段函数,要求编一程序,输入 x,输出相应的 y 的值.分段函数: 输入 一个double类型的数 x 输出 一个double类型的数 y 输入示例 5 输出示例 20 和简单的分段函数(一)异曲同工. 代码: #include<bits/stdc++.h> using namespace std; double x; int main() {

python之内置函数(二)与匿名函数、递归函数初识

一.内置函数(二)1.和数据结构相关(24)列表和元祖(2)list:将一个可迭代对象转化成列表(如果是字典,默认将key作为列表的元素).tuple:将一个可迭代对象转化成元组(如果是字典,默认将key作为元组的元素) 2.相关内置函数(2)reversed:将一个序列翻转,并返回此翻转序列的迭代器. *****slice:构造一个切片模板,用于列表的切片.*** 2-1.reversed()与列表的reverse()区分:列表的reverse()只能列表使用:列表.reverse(),对原列