一.函数对象,函数是第一类对象,即函数可以当做数据传递
- 可以被引用
- 可以当做参数传递
- 返回值可以是函数
- 可以当做容器类型的元素
1.引用函数
def foo(): print('from foo') func=foo print(foo) print(func) func() """ 输出结果: <function foo at 0x0000018D8AC77F28> <function foo at 0x0000018D8AC77F28> from foo """
2.当做参数传递
def foo(): print('from foo') def bar(func): print(func) func() bar(foo) """ 输出结果: <function foo at 0x0000018D8AC77F28> from foo """
3.返回值为函数
def foo(): print('from foo') def bar(func): return func f=bar(foo) print(f) f() """ 输出结果: <function foo at 0x0000018D8AC77F28> from foo
4.可以当做容器类型的元素
def foo(): print('from foo') dic={'func':foo} print(dic['func']) dic['func']() """ 输出结果: <function foo at 0x0000018D8AC77F28> from foo """
二.函数嵌套
1.将两个数字比较的函数嵌套进新函数进行4个数字比较
def max2(x,y): return x if x > y else y def max4(a,b,c,d): res1=max2(a,b) res2=max2(res1,c) res3=max2(res2,d) return res3 print(max4(10,99,31,22)) """ 输出结果: 99 """
2.函数嵌套的定义
def f1(): def f2(): print('from f2') def f3(): print('from f3') f3() f2() f1() """ 输出结果: from f2 from f3 """
三.名称空间与作用域
1.内置名称空间:随着python解释器的启动而产生
print(max([1,2,3])) """ 输出结果: 3 """ import builtins for i in dir(builtins): print(i) """ 输出结果: 查看内置名称空间 """
2.全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入改空间
x=2 def func(): money=2000 x=2 print('func') print(x) print(func) func() func() print(x) """ 输出结果: func func 2 """
3.局部名称空间:调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束解绑定
x=10000 def func(): x=1 def f1(): pass
4.作用域:
全局作用域:内置名称空间,全局名层空间。
局部作用:局部名称空间。
a.名字的查找顺序:局部名称空间---》全局名层空间---》内置名称空间
x=1 def func(): x=2 print(x) sum=123123 print(sum) func() """ 输出结果: 2 123123 """
b.查看全局作用域内的名字:gloabls(),查看局局作用域内的名字:locals()
x=1000 def func(): x=2 print(globals()) print(locals()) print(globals() is locals()) """ 输出结果: Ture """
x=1000 def func(y): x=2 print(locals()) print(globals()) func(1)
c.全局作用域与局部作用域
全局作用域:全局有效,在任何位置都能被访问到,除非del删掉,否则会一直存活到文件执行完毕
局部作用域的名字:局部有效,只能在局部范围调用,只在函数调用时才有效,调用结束就失效
x=1 def foo(): print(x) foo() def f(x): # x=4 def f2(): x=3 print(x) def f3(): x=2 print(x) f3() f2() f(4) """ 输出结果: 1 3 2 """
四.闭包函数
- 定义在函数内部
- 包含对外部作用域而非全局作用域的引用
def f1(): x = 1 def f2(): x = 5 print(x) return f2 f=f1() f() """ 输出结果: 5 """
2.闭包应用:惰性计算
from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get res=index('http://www.baidu.com') print(res().decode('utf-8')) # 查看闭包元素 print(res.__closure__[0].cell_contents)
五.装饰器
- 修饰别人的工具,修饰添加功能,工具指的是函数。
- 装饰器本身可以是任何可调用对象,被装饰的对象也可以是任意可调用对象
1.无参装饰器
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 wrapper @timmer def index(): time.sleep(3) print('welcome to index') index()
2.有参装饰器
login_user={'user':None,'status':False} def auth(func): def wrapper(*args,**kwargs): if login_user['user'] and login_user['status']: res=func(*args,**kwargs) return res else: name=input('>>: ') password=input('>>: ') if name == 'json' and password == '123': login_user['user']='json' login_user['status']=True print(' 33[45mlogin successful 33[0m') res=func(*args,**kwargs) return res else: print(' 33[45mlogin err 33[0m') return wrapper @auth def index(): print('welcome to index page') @auth def home(name): print('%s welcome to home page' %name) index() home('json') ''' 输出结果: login successful welcome to index page json welcome to home page '''
六.迭代器
(1)迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。迭代器只能往前不会后退.
(2)对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。迭代器更大的功劳是提供了一个统一的访问集合的接口,只要定义了__iter__()方法对象,就可以使用迭代器访问。
1.next 进行遍历
list = [1, 2, 3, 4] it = iter(list) # 创建迭代器对象 while True: try: print(next(it)) except StopIteration: break
2.__next__() 返回迭代器的下一个元素
names = iter(['json','nickle','alex']) print(names) print(names.__next__()) print(names.__next__()) print('暂停') print(names.__next__()) ''' 输出结果: <list_iterator object at 0x000001FF1BB1A8D0> json nickle 暂停 alex '''
3.__iter__()返回迭代器对象本身
names = iter(['json','nickle','alex']) print(names.__iter__()) ''' 输出结果: <list_iterator object at 0x000001ED14FFAD30> 暂停 alex '''
七.生成器
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
yield的功能:
①相当于为函数封装好__iter__和__next__;
②每次遇到 yield 时,挂起函数的运行状态,返回yield的值。并在下一次执行 next()方法时,从当前位置继续运行。
注意事项:生成器只能遍历一次
def grep(pattern, lines): for line in lines: if pattern in line: yield line g = grep('python', tail('a.txt')) print(g) for i in g: print(i)
八.内置函数
1.abs( ):返回数字的绝对值
print(abs(-222))
2.all()集合中的函数如都为真返回True
lis = [1,2,3] print(all(lis)) # True
3.any()list中的元素一个为真时,返回True,空返回False
lis = [1,2,3] a = [] print(any(lis)) # True print(any(a)) # False
4.chr()返回整数对应的Ascii对应的字符
print(chr(66)) # B
5.ord()将整数返回字符对应的ASC编码
print(ord('B'))
6.bin()将整数转换为二进制字符串
print(bin(77)) # 0b1001101
7. bool(x)返回x的布尔值
print(bool(0)) # False print(bool(1)) # True
8.dir()不带参数时,返回当前范围内的变量、方法和定义的类型列表,带参数时,返回参数的属性、方法列表
print(dir()) print(dir(list))
9.divmod()分别取商和余数
print(divmod(66,7)) ''' 输出结果: (9, 3) '''
10.enumerate()返回一个可枚举的对象,该对象的next()方法将返回一个tuple
lis = ["json", "nickle", "lyl"] for m, n in enumerate(lis): print(m,n) ''' 输出结果: 0 json 1 nickle 2 lyl '''
11.eval()将字符串str当成有效的表达式来求值并返回计算结果。
lis = '[{"json": 20}, {"nickle":90}, {"lyl": 70}]' name = eval(lis) print(name) ''' 输出结果: [{'json': 20}, {'nickle': 90}, {'lyl': 70}] '''
12.filter(function, iterable):过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的生成器(py2返回序列)
- function---判断函数
- iterable---可迭代对象
newlist = filter(None, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in newlist: print(i)
13.float([x]):将整数和字符串转换成浮点数
print(float(88)) print(float(123)) ''' 输出结果: 88.0 123.0 '''
14.dict():创建一个字典
print(dict(a = "1", b = "2")) ''' 输出结果: {'a': '1', 'b': '2'} '''
15.id()返回对象地址
print(id("uhuh")) ''' 输出结果: 2926276336752 '''
16.callable(object):检测一个对象是否是可调用的
对于函数, 方法, lambda 函数, 类, 以及实现了 __call__ 方法的类实例, 它都返回 True
def add(a, b): return a + b print(callable(add)) print(callable("abc")) ''' 输出结果: True False '''