学习函数的作用:
将可能需要反复执行的代码封装为函数,并在需要该功能的地方进行调用,不仅可以实现代码复用 ,更重要的是可以保证代码的一致性,只需要修改该函数代码则所有调用均受到影响。设计函数时,应注意提高模块的内聚性,同时降低模块之间的隐式耦合def 函数名(参数列表):
函数体
如果要写注释的话可以用下面的:
def 函数名(参数列表):
"’ 注释 "’
函数体
注意
python函数不需要声明参数的类型,以及不需要指定返回值类型函数名后的括号和冒号是必写的函数体相对于def关键字必须保持一定的空格缩进python允许嵌套定义函数 def FunctionName(p): """ 注释 :param p: 参数 :return: """ print("这是函数体","参数的值:",p) def FunctionName1(): """ 没有参数也要有空格。 :return: """ print("这是必须的")对函数返回值得解释:
定义函数时也不需要声明函数的返回值类型,而是使用return语句结束函数执行的同时返回任意类型的值,函数返回值类型与return语句返回表达式的类型一致,不论return语句出现在函数的什么位置,一旦得到执行将直接结束函数的执行。
若函数没有return语句、有return语句但是没有执行到或者执行了不返回任
何值的return语句,解释器都会认为该函数以return None结束,即返回空值。
Python允许函数的嵌套定义,在函数内部可以再定义另外一个函数
def Mp(iterable, op, value): #自定义函数 if op not in '+-*/': return '错误!' # 嵌套定义函数 def nested(item): """ 嵌套函数 只能在该函数内部调用 repr():返回对象的规范字符串表示形式。 eval(string):可以接受一个字符串str作为参数,并把这个参数作为脚本代码来执行。 :param item: :return: """ return eval(repr(item)+op+repr(value)) # 使用在函数内部定义的函数 return map(nested, iterable) list(Mp(range(5), '+', 5)) #调用外部函数,不需要关心其内部实现函数属于Python可调用对象之一,由于构造方法的存在,类也是可调用的。像list()、tuple()、dict()、set()这样的工厂函数实际上都是调用了类的构造方法。另外,任何包含__call__()方法的类的对象也是可调用的
class linear: """ __init__()方法被称为构造器(constructor)。 __init__函数两个下划线开头的函数是声明该属性为私有, 不能在类的外部被使用或访问。 而__init__函数(方法)支持带参数类的初始化, 也可为声明该类的属性(类中的变量)。 __init__函数(方法)的第一个参数必须为self, 后续参数为自己定义。 __call__:实例魔法方法,可以把类实例当做函数调用 """ def __init__(self, a, b): self.a, self.b = a, b def __call__(self, x): #这里是关键 return self.a * x + self.b taxes = linear(0.3, 2) print(taxes(5)) print(taxes.__call__(5)) #taxes(5) == taxes.__call__(5) # 3.5 # 3.5修饰器(decorator)是函数嵌套定义的另一个重要应用。修饰器本质上也是一个函数,只不过这个函数接收其他函数作为参数并对其进行一定的改造之后使用新函数替换原来的函数 。
Python面向对象程序设计中的静态方法、类方法、属性等也都是通过修饰器实现的。
在Python中,函数是first class citizen,函数本身也是对象,这意味着我们可以对函数本身做很多有意义的操作。
在设计模式中,decorator能够在无需直接使用子类的方式来动态地修正一个函数,类或者类的方法的功能。当你希望在不修改函数本身的前提下扩展函数的功能时非常有用。
简单地说,decorator就像一个wrapper一样,在函数执行之前或者之后修改该函数的行为,而无需修改函数本身的代码,这也是修饰器名称的来由。
import time def timmer(fun1): print("这是第一个") def wrapper(*args,**kwargs): start_time=time.time() res=fun1(*args,**kwargs) stop_time=time.time() print('运行时间 is %s' %(stop_time-start_time)) print("第一个结束") return res return wrapper def func(fun): print("这是第二个") def wrapper(*args,**kwargs): run = fun(*args,**kwargs) print("第二个结束") return run return wrapper #多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身。 @timmer @func def foo(): time.sleep(3) print('foo') @timmer def foo1(): time.sleep(5) print('foo1') foo() #这是第二个 # 这是第一个 # 这是第一个 # foo # 第二个结束 # 运行时间 is 3.0000123977661133 # 第一个结束 # Before function called. # 3 # After function called.可以有参和无参
有参
def fun(a, b, c): 不需要声明参数类型
def fun(a, b,*args ,** kwargs):
位置参数(**positional arguments)是比较常用的形式,调用函数时实参和形参的顺序必须严格一致,并且实参和形参的数量必须相同
可以改变实参:传递给函数的参是可变序列,并且在函数内部使用下标或 可变序列自身的方法增加、删除元素或修改元素时,实参也得到相应的修改。
默认参数:即给定默认值的参数,可以改变
关键参数:主要指调用函数时的参数传递方式,与函数定义无关。通过关键参数可以按参数名字传递值,明确指定哪个值传递给哪个参数
变长度参数:在参数名前加1个*或2个* 例如:*args ,** kwargs 分别返回 元组和字典
注意: *args 和 ** kwargs
*args 返回元组
** kwargs 返回字典
默认参数:在定义带有默认值参数的函数时,任何一个默认值参数右边
都不能再出现没有默认值的普通位置参数,否则会提示语法错误,
实例
def fun(a, b, c, *args,m=2,k=3.14,**kwargs,): """ a,b,c 为位置参数 m , k 为默认参数 :param args: :param kwargs: :return: """ print(type(a),type(b),type(c)) print("*args:",type(args),args) print("**kwargs:",type(kwargs),kwargs) print('m,k ==',m,k) fun(1,"5", 25.3,25,14.5,"scasc", m=25, k=69, name='baiye', password='123456',valeu=25) #结果: #<class 'int'> <class 'str'> <class 'float'> *args: <class 'tuple'> (25, 14.5, 'scasc') #**kwargs: <class 'dict'> {'name': 'baiye', 'password': '123456', 'valeu': 25} #m,k == 25 69修饰器那部分(不是特别理解)可参考:Python–Wrapper-博客园-作者eilinge
