函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
语法
def functionname( parameters ): "函数_文档字符串" function_suite return [expression]
(1)PEP8 编码规范, 及开发中的一些惯例和建议
代码编排:
缩进 4 个空格, 禁止空格与 Tab 混用
行长 80: 防止单行逻辑过于复杂
缩进式,块级, 对齐风格 —— 函数功能块
import
不要使用
from xxx import *
顺序
标准库
第三方库
自定义库
单行不要 import 多个库
模块内用不到的不要去 import
空格
: , ;
后面跟一个空格, 前面无空格 (行尾分号后无空格)二元操作符前后各一个空格, 包括以下几类:
数学运算符:
+ - * / // = & |
比较运算符:
== != > < >= <= is not in
逻辑运算符:
and or not
位运算符:
& | ^ << >>
当
=
用于指示关键字参数或默认参数值时, 不要在其两侧使用空格
适当添加空行
函数间: 顶级函数间空 2 行, 类的方法之间空 1 行
函数内: 同一函数内的逻辑块之间, 空 1 行
文件结尾: 留一个空行 (Unix 中 \n 是文件的结束符)
注释
忌: 逐行添加注释, 没有一个注释
行内注释: 单行逻辑过于复杂时添加
块注释: 一段逻辑开始时添加
引入外来算法或者配置时须在注释中添加源连接, 标明出处
函数和类尽可能添加
docstring
命名
除非在 lambda 函数中, 否则不要用 单字母 的变量名 (即使是 lambda 函数中的变量名也应该尽可能的有意义)
包名、模块名、函数名、方法名全部使用小写, 单词间用下划线连接
类名、异常名使用 CapWords (首字母大写) 的方式, 异常名结尾加
Error
或Wraning
后缀全局变量尽量使用大写, 一组同类型的全局变量要加上统一前缀, 单词用下划线连接
字符串拼接尽量使用
join
方式: 速度快, 内存消耗小语意明确、直白
not xx in yy
VSxx not in yy
not a is b
VSa is not b
程序的构建
一个函数只做一件事情, 并把这件事做好
大的功能用小函数之间灵活组合来完成
避免编写庞大的程序, “大” 意味着体积庞大, 逻辑复杂甚至混乱
函数名必须有动词, 最好是 do_something 的句式, 或者 somebody_do_something 句式
自定义的变量名、函数名不要与标准库中的名字冲突
pip install pep8 pylint flake8
练习: 规范化这段代码
from django.conf import settings import sys, os mod=0xffffffff def foo (a , b =123 ): c= { 'x' : 111 , 'y' : 222}#定义一个字典 d =[1, 3 ,5 ] return a ,b, c def bar(x): if x%2== 0: return True
变量与对象
Python 中一切皆为对象,数字是对象,列表是对象,函数也是对象,任何东西都是对象。而变量是对象的一个引用(又称为名字或者标签),对象的操作都是通过引用来完成的。例如,[]是一个空列表对象,变量 a 是该对象的一个引用
在 Python 中,「变量」更准确叫法是「名字」,赋值操作 = 就是把一个名字绑定到一个对象上。就像给对象添加一个标签。
a =
1 整数 1 赋值给变量 a 就相当于是在整数1上绑定了一个 a 标签。
a =2 整数 2 赋值给变量 a,相当于把原来整数 1 身上的 a 标签撕掉,贴到整数 2 身上。
b =
a 把变量 a 赋值给另外一个变量 b,相当于在对象 2 上贴了 a,b 两个标签,通过这两个变量都可以对对象 2 进行操作。
看一下代码段
def bar(args):
args.append(1)
b = []
print(b) # 输出:[]
print(id(b)) # 输出:4324106952
bar(b)
print(b) #输出:[1]
print(id(b)) # 输出:4324106952
(2)* 和 ** 的用法
函数定义
def foo(*args, **kwargs): pass
参数传递
def foo(x, y, z, a, b): print(x) print(y) print(z) print(a) print(b) lst = [1, 2, 3] dic = {'a': 22, 'b': 77} foo(*lst, **dic)
import * 语法
文件 xyz.py
__all__ = ('a', 'e', '_d') a = 123 _b = 456 c = 'asdfghjkl' _d = [1,2,3,4,5,6] e = (9,8,7,6,5,4)
文件 abc.py
from xyz import * print(a) print(_b) print(c) print(_d) print(e)
强制命名参数
def foo(a, *, b, c=123): pass
解包语法: a, b, *ignored, c = [1, 2, 3, 4, 5, 6, 7]
匿名函数
python 使用 lambda 来创建匿名函数。
lambda只是一个表达式,函数体比def简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法
lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
例子:
# 可写函数说明 sum = lambda arg1, arg2: arg1 + arg2; # 调用sum函数 print("相加后的值为 : ", sum(10, 20)) print("相加后的值为 : ", sum(20, 20))
函数作为对象
# 可写函数说明 def sum(arg1, arg2): # 返回2个参数的和." total = arg1 + arg2 print("函数内 : " + str(total)) return total; # 调用sum函数 total = sum(10, 20); print(total)
函数身为一个对象,拥有对象模型的三个通用属性:id、类型、和值。
def foo(): print('from foo') foo() print(id(foo)) print(type(foo)) print(foo)
函数可以被引用,即函数可以赋值给一个变量
def foo(): print('from foo') foo() func=foo #引用,赋值 print(foo) print(func) func()
函数接受一个或多个函数作为输入或者函数输出(返回)的值是函数时,我们称这样的函数为高阶函数
def foo(): print('from foo') def bar(func): return func f=bar(foo) print(f) f()
容器对象(list、dict、set等)中可以存放任何对象,包括整数、字符串,函数也可以作存放到容器对象中
def foo(): print('from foo') dic={'func':foo} foo() print(dic['func']) dic['func']()