您的位置:首页 > 编程语言 > Python开发

Python--函数对象@命名空间与作用域@包函数@装饰器@迭代器@内置函数

2017-05-27 16:01 423 查看

一、函数对象

函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性。

那到底什么是第一类对象(First-Class Object)呢?

在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量、可以作为元素添加到集合对象中、可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的。

1.函数身为一个对象,拥有对象模型的三个通用属性:id、类型、和值。

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 def foo():
4     print('from foo')
5 foo()
6
7 print(id(foo))
8 print(type(foo))
9 print(foo)
View Code

输出

from foo
4406808360
<class 'function'>
<function foo at 0x106aa8f28>

2.函数可以被引用,即函数可以赋值给一个变量

还可以把该函数赋值给更多的变量,唯一变化的是该函数对象的引用数不断地增加,本质上这些变量最终指向的都是同一个函数对象。

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 def foo():
4     print('from foo')
5
6 foo()
7 func=foo    #引用,赋值
8 print(foo)
9 print(func)
10 func()
View Code

输出

from foo
<function foo at 0x10eed8f28>
<function foo at 0x10eed8f28>
from foo

 

3.函数可以当做参数传递

def foo():
print('from foo')

def bar(func):
print(func)
func()

bar(foo)

输出

<function foo at 0x1047eff28>
from foo

 

4.函数可以作返回值

函数接受一个或多个函数作为输入或者函数输出(返回)的值是函数时,我们称这样的函数为高阶函数

def foo():
print('from foo')

def bar(func):
return func

f=bar(foo)

print(f)

f()

输出

<function foo at 0x107f29f28>
from foo

 

5.函数可以当作容器类型的元素

容器对象(list、dict、set等)中可以存放任何对象,包括整数、字符串,函数也可以作存放到容器对象中

def foo():
print('from foo')
dic={'func':foo}

foo()

print(dic['func'])

dic['func']()

输出

from foo
<function foo at 0x10997ef28>
from foo

 

6.函数还可以嵌套

函数嵌套的定义

def f1():

def f2():
print('from f2')
def f3():
print('from f3')
f3()
f2()

f1()

输出

from f2
from f3

 

 

二、命名空间与作用域 

命名空间是名字和对象的映射,就像是字典,key是变量名,value是变量的值

1.命名空间的定义

name='egon'  #定义变量

def func():  #定义函数
pass

class Foo:  #定义类
pass

 

2.命名空间的分类

  • 1.内置名称空间: 随着python解释器的启动而产生,包括异常类型、内置函数和特殊方法,可以代码中任意地方调用
print(sum)
print(max)
print(min)

print(max([1,2,3]))

import builtins
for i in dir(builtins):   #打印所有的内置函数
print(i)

输出

1 def a(name):#与装饰器对应的函数
2     name()
3
4 @a#装饰器  b = a(b)
5 def b():#被装饰函数
6     print('zjl')
View Code

 

输出

zjl

解析过程是这样子的:
1.python 解释器发现@a,就去调用与其对应的函数( a 函数)
2.a 函数调用前要指定一个参数,传入的就是@a下面修饰的函数,也就是 b()
3.a() 函数执行,调用 b(),b() 打印“zjl”

 

5.装饰器的应用

1 import time
2
3 def timmer(func):
4     def wrapper():
5         start_time=time.time()
6         func()       #index()
7         stop_time=time.time()
8         print('run time is %s' %(stop_time-start_time))
9     return wrapper
10
11
12 @timmer       #index=timmer(index)
13 def index():
14     time.sleep(1)
15     print('welcome to index')
16
17 index()
View Code

输出

welcome to index
run time is 1.005241870880127

 

例子

 

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 == 'zjl' and password == '123':
login_user['user']='hexin'
login_user['status']=True
print('\033[45mlogin successful\033[0m')
res=func(*args,**kwargs)
return res
else:
print('\033[45mlogin err\033[0m')
return wrapper

@auth     #index=auth(index)
def index():
print('welcome to index page')

@auth      #home=auth(home)
def home(name):
print('%s welcome to home page' %name)

index()
home('zjl')

 

 

输出

请输入用户名: zjl
请输入密码: 123
login err
请输入用户名: zjl
请输入密码: 123
login successful
hexin welcome to home page

 

补充:

装饰器的基本框架:

def timer(func):
def wrapper():
func()
return wrapper

 带参数

def timer(func):
def wrapper(*args,**kwargs):
func(*args,**kwargs)
return wrapper

 

六、可迭代对象和迭代器

1.迭代的概念

上一次输出的结果为下一次输入的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值 

注:循环不是迭代

while True: #只满足重复,因而不是迭代
print('====>')

 

2.可迭代的对象

内置__iter__方法的,都是可迭代的对象。

list是可迭代对象,dict是可迭代对象,set也是可迭代对象。

[1,2].__iter__()
'hello'.__iter__()
(1,2).__iter__()

{'a':1,'b':2}.__iter__()
{1,2,3}.__iter__()

 

例如:

x = [1, 2, 3]
y = iter(x)
z = iter(x)
print(next(y))
print(next(y))
print(next(z))
print(type(x))
print(type(y))

输出

1
2
1
<class 'list'>
<class 'list_iterator'>

  

这里

x
是一个可迭代对象,
y
z
是两个独立的迭代器,迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。

迭代器有一种具体的迭代器类型,比如

list_iterator
set_iterator
。可迭代对象实现了
__iter__
方法,该方法返回一个迭代器对象。

 

3.迭代器

  • 1.为什么要有迭代器?

对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式。

 

  • 2.迭代器定义:

迭代器:可迭代对象执行__iter__方法,得到的结果就是迭代器,迭代器对象有__next__方法

它是一个带状态的对象,他能在你调用

next()
方法的时候返回容器中的下一个值,任何实现了
__iter__
__next__()
方法的对象都是迭代器,
__iter__
返回迭代器自身,
__next__
返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常

  • 3.迭代器的实现

例:

i=[1,2,3].__iter__()

print(i)    #迭代器

print(i.__next__())
print(i.__next__())
print(i.__next__())
#print(i.__next__()) #抛出异常:StopIteration

输出

<list_iterator object at 0x1019c3eb8>
1
2
3

每次调用

next()
方法的时候做两件事: 

  1. 为下一次调用
    next()
    方法修改状态
  2. 为当前这次调用生成返回结果

迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

 

  • 4.如何判断迭代器对象和可迭代对象
from collections import Iterable,Iterator
'abc'.__iter__()
().__iter__()
[].__iter__()
{'a':1}.__iter__()
{1,2}.__iter__()

f=open('a.txt','w')
f.__iter__()

#判断是否为可迭代对象,以下都是 print(isinstance('abc',Iterable)) print(isinstance([],Iterable)) print(isinstance((),Iterable)) print(isinstance({'a':1},Iterable)) print(isinstance({1,2},Iterable)) print(isinstance(f,Iterable))
#判断是否为迭代器,只有文件是 print(isinstance('abc',Iterator)) print(isinstance([],Iterator)) print(isinstance((),Iterator)) print(isinstance({'a':1},Iterator)) print(isinstance({1,2},Iterator)) print(isinstance(f,Iterator))

输出

True
True
True
True
True
True
False
False
False
False
False
True

 

可迭代对象:只有__iter__方法,执行该方法得到的迭代器对象

迭代器:有

__iter__
__next__()
方法

注:对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身

 

  • 5.迭代器的优点和缺点

优点:
1.提供了一种不依赖下标的迭代方式
2.就跌迭代器本身来说,更节省内存

缺点:
1. 无法获取迭代器对象的长度
2. 不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退

 

七、内置函数

简单来说就是python3本身就自带的函数。

 View Code  

  •  zip()  

将对象逐一配对

s='helloo'
l=[1,2,3,4,5]

z=zip(s,l)
print(z)
for i in z:
print(i)
<zip object at 0x1051d1608>
('h', 1)
('e', 2)
('l', 3)
('l', 4)
('o', 5)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: