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

python函数基础

2017-12-19 15:50 357 查看
一、为什么要有函数?没有函数有什么问题?
1、组织结构不清晰,可读性差
2、代码冗余
3、可扩展性差
二、函数的分类:
1、内置函数:python解释器已经为我们定义好了的函数即内置函数,我们可以拿来就用而无需事先定义
2、自定义函数:我们自己根据需求,事先定制好我们自己的函数来实现某种功能,如果遇到相同的情景可以直接调用
三、定义函数的三种形式
第一种:无参函数 (应用场景仅仅只是执行一些操作)

def foo():
print('from foo')
第二种:有参函数 (需要根据外部传进来的参数,才能执行相应的逻辑)
有参函数分为形参和实参

形参包含:
1、位置形参:必选参数

def foo(name,age,sex):
print(name)
print(age)
print(sex)
2、默认函数:形参在定义时就已经为其赋值
实参包含:
1、关键字实参:按照key=value的形式定义的实参
2、位置实参:按照位置给形参传值
foo('jim',18,'male')
还有一种是可变长参数:可变长参数指的是实参的个数多了,实参无非位置实参和关键字实参两种
形参处理按照位置定义的实参溢出的情况:*

def foo(x,y,*args):          #*把位置实参多余的赋值给args, args=(3, 4, 5)
print(x)
print(y)
print(args)
foo(1,2,3,4,5)


形参处理按照关键字定义的实参溢出的情况:**

def foo(x,y,**awargs):          #**把位置实参多余的赋值给awargs, awargs={'z': 3, 'e': 4}
print(x)
print(y)
print(awargs)
foo(x=1,y=2,z=3,e=4)
最后是命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递

def foo(x,y,*args,a=1,**kwargs):
print(x, y)           #处理传的参数后结果是1 2
print(args)           #处理传的参数后结果是(3, 4, 5)
print(a)               #处理传的参数后结果是1
print(kwargs)         #处理传的参数后结果是{'c': 4, 'd': 5}
foo(1,2,3,4,5,c=4,d=5)
第三种:空函数 (设计代码结构)
四、函数调用
1、函数的返回值

return的返回值没有类型限制
1. 没有return:返回None,等同于return None
2. return 一个值:返回该值
3. return 多个值:返回的多个值以元组的形式
2、函数调用的三种形式
1、语句形式

2、表达式形式
3、当做另外一个函数的参数

def foo(x,y):
if x>=y:
return x
else:
return y
foo(1,2)                    #语句形式
res=foo(1,2)*10       #表达式形式,取到的结果在表达式里做运算
res2=foo(foo(1,2),3) #函数调用可以当做另外一个函数的参数
print(res2)


五、名称空间与作用域
1、名称空间的加载顺序
#1、python解释器先启动,因而首先加载的是:内置名称空间
#2、执行*.py文件,然后以文件为基础,加载全局名称空间
#3、在执行文件的过程中如果调用函数,则临时产生局部名称空间
2、名称空间的查找顺序

局部名称空间--->全局名称空间--->内置名称空间

3、作用域
作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关

x=1
def num():
x=2
print(x)                    #x的值为2
x=3
num()


六、闭包函数

1、闭包函数: 内部函数包含对外部作用域而非全局作用域的引用
2、闭包函数的意义

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

import requests
def outter(url):
# url = 'https://www.baidu.com'
def get():
response=requests.get(url)
if response.status_code == 200:                #取状态码是200的
print(len(response.text))
return get
baidu=outter('https://www.baidu.com')
baidu()


七、装饰器
1、遵循的原则
开放封闭原则:对修改封闭,对扩展开放

1、不修改被装饰对象的源代码
2、不修改被装饰对象的调用方式
2、模拟打开网页的时间

import time
def index():
time.sleep(3)
print('hello')
def inner():
start=time.time()                           #开始的时间
index()
stop=time.time()                          #网页打开后的时间
print(stop-start)
inner()


上面的实现了我们的需要,但是inner函数包含index函数,只能统计index的执行时间,不利于代码的重用,所以要改进一下

import time
def index():
time.sleep(3)
print('hello')
def timmer(func):
def inner():
start=time.time()
func()
stop=time.time()
print(stop-start)
return inner
index=timmer(index)    #index不是以前的index,是重新更名的,这样对用户调用index函数时,操作不会改变
index()
改为装饰器语法的写法:

import time
def timmer(func):
def inner():
start=time.time()
func()
stop=time.time()
print(stop-start)
return inner
@timmer        #装饰器的语法,相当于index=timmer(index)
def index():
time.sleep(1)
print('hello')
index()


最后版本

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(1)
print('from foo')
foo()


执行流程:程序执行时,执行@timmer,会识别成index=timmer(index),跳到timmer函数,执行到return wrapper--> @timmer--->foo()--->执行wrapper函数--->执行之前定义的foo()---->结果赋值给res---->返回res,所以打印的结果会是from foo,然后打印执行的时间
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 def