Python 函数
系统函数使用,自定义函数,函数的参数。
一、系统函数
Python内置很多函数供开发这调用,如abs()求绝对值。help()查看某个函数的使用等。
调用系统函数如下:
>>> help(abs) Help on built-in function abs in module builtins: abs(x, /) Return the absolute value of the argument. >>> >>> abs(-1) 1 >>>
如下是摘自官方网站一张系统函数表格:https://docs.python.org/3/library/functions.html#abs
二、自定义函数
在Python中定义一个函数需要用到Python中的关键字def定义语句。流程如下
def 方法名(参数):
方法体
return 返回值.
1 >>> def myMax(x, y): 2 ... if x > y: 3 ... return x 4 ... else: 5 ... return y 6 ... 7 >>> myMax(1,2) 8 2 9 >>>
第二行特别注意要缩进,然后否则会报错,缩进规则第二行比第一行随进一个单位或者更多<最好是一个,因为同级别的代码块需要保持一致,例如第四行>,对于第三行需要在第二行的基础上再次缩进一个单位。这里结束一个方法的编写需要回车两次。
然后直接在命令行调用声明过的方法,验证结果是否正确。函数这里声明的时候并未声明返回值类型,所以这里可以任意,如果你不提供返回值也无所谓,系统自己会默认返回None。
1 >>> def myMax(x, y): 2 ... if x > y: 3 ... pass 4 ... 5 >>> myMax(1,2) 6 >>>
类导入
导入格式如下 from module_class_name
调用导入类中的方法
module_class_name.method_name().
方法导入
导入格式如下 from module_class_name import method_name
空函数<关键字pass>
空函数定义如下
>>> def empty():
... pass
...
>>>
pass作用仅仅是编译不报错,pass作为方法体的一部分,如果不存在则程序语法就不完整编译会失败。
形参传入非法类型
1 >>> def myMax(x, y): 2 ... if x > y: 3 ... return x 4 ... else : 5 ... return y 6 ... 7 >>> myMax('a', 'b') 8 'b' 9 >>> myMax('a', 2) 10 Traceback (most recent call last): 11 File "<stdin>", line 1, in <module> 12 File "<stdin>", line 2, in myMax 13 TypeError: '>' not supported between instances of 'str' and 'int' 14 >>>
声明方法求最大值的方法,形参类型是整形,但是编译器并不会为我们判断出入的参数是否合法。第七行很我直接传入的两个不同的字符,很显然在进行比较的时候转换成对应的ASCII进行了比较,所以没有任何问题。但是对于不同类型整形和字符则直接抛出类型错误。
一个方法返回多个值
>>> def multi(): ... return 1, 2, 3 ... >>> multi() (1, 2, 3) >>>
如上定义一个方法返回多个参数。其实自己观察返回值会发现,返回的数据其实是一个Tuple元组。那么代码是不是可以这么写那?
>>> def multi(): ... return (1, 2, 3) ... >>> multi() (1, 2, 3) >>> >>> def multi(): ... return [1, 2, 3] ... >>> multi() [1, 2, 3] >>>
既然返回的结果还是一个元组,那么根据元组定义给返回值增加括号也是合理的,经验证确实咱们的猜想是合理的。
既然返回值可以是元组,我们猜想可以是列表么List,当然上边代码的执行结果告诉了我们也是可以的。对于数据而已方式包含了元组,列表,字典,集合。至于其他的可以自己动手验证下。
三、函数参数
注:如上已经验证了一个问题,编译器并不会对形参类型进行编译检查,只有在执行的时候才会触发,直接抛出类型错误.
方法参数<形参>种类:
位置参数,默认参数,可变参数,命名关键字参数,关键字参数<形参排列顺序>
位置参数:
位置参数就是方法使用过程中正常声明的形参,如empty(x),这里x就是位置参数。
默认参数:
默认参数可以当做是对位置参数的一种扩展,其目的是为了传入参数的简化。
如下代码:
1 >>> def enroll(name, age, sex='man'): 2 ... print('name:', name, " age:", age, ' sex:', sex) 3 ... 4 >>> enroll('ArMn', 25) 5 name: ArMn age: 25 sex: man 6 >>> enroll('Alice', 21, 'woman') 7 name: Alice age: 21 sex: woman 8 >>>
声明方法学生登记方法,默认性别为男性,在执行方法enroll的时候,可以不传入改字段,也可以传入该字段。
这里有个问题,如果是多个默认参数的时候处理,假如有性别和民族,我想给民族传入参数并且同时需要性别使用默认值怎么办???
1 >>> def enroll(name, age, sex='man', nation='han'): 2 ... print('name:', name, " age:", age, ' sex:', sex, ' nation:', nation) 3 ... 4 >>> enroll('ArMn', 25, nation='min') 5 name: ArMn age: 25 sex: man nation: min 6 >>>
这里可以通过默认参数传值的另一种方式形参名=形参值。这里还是简单的两种传值方式。
可变参数
可变参数是可以不指定具体传入的参数类型和数量。例如需求求一组数据的和,这时候你并不知道传入的参数的有多少。那么可变参数就迎来了属于他的春天。
1 >>> def sum(*array): 2 ... sum = 0 3 ... for single in array: 4 ... sum = sum + single 5 ... return sum 6 ... 7 >>> sum(1,2,3) 8 6 9 >>> sum(*[1,2]) 10 3 11 >>>
可变参数用标记*来表示。调用方式两种直接传入多个值,另一中方式传入一个列表,但是必须用标记*来标记,否则解析会失败提示类型错误。
>>> def sum(*array): ... sum = 0 ... for single in array: ... sum = sum + single ... return sum ... >>> sum([1,2,3]) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in sum TypeError: unsupported operand type(s) for +: 'int' and 'list'
关键字参数
关键字参数允许你传入多个对应的key-value的值
关键字参数声明**args,对比可变参数多了一个标记*。关键字参数会内部实现组装该参数为了一个字典dict<关键字参数允许传入类似可变参数的多个形参>。具体看入下示例;
>>> def stu(name, age, **city): ... print('name:', name, ' age:', age,'city:', city) ... >>> stu('ArMn', 25, city='河南') name: ArMn age: 25 city: {'city': '河南'} >>>
定义方法学生,录入学生姓名,年龄,以及所在城市<这里采用的关键字参数代替>,可以看大输出的city中对应是一个字典dict,也就验证了如上说到的内容。
>>> stu('ArMn', 25, city='河南', area='洛阳') name: ArMn age: 25 city: {'city': '河南', 'area': '洛阳'} >>>
如上是为了验证关键字参数是否支持传入多个参数,输出结果验证了确实关键字参数用于可变参数的特性。那么是不是拥有了关键字参数就不需要了可变参数了?当然不是,可变参数擦传入的参数和关键字参数传入的参数就格式上来说还是存在很大差异。
命名关键字参数
命名关键字参数是对关键字参数的进一步的约束,可以简单理解为让关键字参数失去可变参数的特性。
声明关键字*,格式method(args,*,args1,args2...);
1 >>> def stu(name, age, *,city,job): 2 ... print('name:',name, 'age:',age, 'city:',city,'job:',job) 3 ... 4 >>> stu('ArMn', 25, city='henan', job='dev') 5 name: ArMn age: 25 city: henan job: dev 6 >>> 7 >>> stu('ArMn', 25, city='henan', jo='dev') 8 Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10 TypeError: stu() got an unexpected keyword argument 'jo' 11 >>>
第一行声明一个包含了命名关键字的方法,从方法调用传值上来看类似关键字参数,但是不同点是关键字参数最终会被封装成字典dict,对于命名关键字而已最终显示的结果等同于位置参数,并且命名关键字参数传入的值正确的时候(第七行,job=>jo),则直接报类型错误。所以命名关键字有着key-value的严格要求。同时命名关键字不具备传入多个可变参数的特性。
命名关键字参数的严格和可变参数特性的丢失。
1 >>> stu('ArMn', 25, city='henan', job='dev',other='') 2 Traceback (most recent call last): 3 File "<stdin>", line 1, in <module> 4 TypeError: stu() got an unexpected keyword argument 'other' 5 >>> 6 >>> stu('ArMn', 25, 'henan', dev') 7 File "<stdin>", line 1 8 stu('ArMn', 25, 'henan', dev') 9 ^ 10 SyntaxError: EOL while scanning string literal 11 >>>
可变参数和命名关键字
命名关键字前如果存在参数并且是可变参数其*可以省略。
1 >>> def stu(name, age, *args,city,job): 2 ... print('name:',name,'age:',age,'args:',args,'city:',city,'job:',job) 3 ... 4 >>> 5 >>> 6 >>> stu('ArMn',25,*[1,2,4],city='henan',job='dev') 7 name: ArMn age: 25 args: (1, 2, 4) city: henan job: dev 8 >>>
最后重申下方法参数排列顺序
位置参数->默认参数->可变参数->命名关键字参数->关键字参数