Functions and packages in Python

Introduction to creat and use functions and packages in Python

Posted by Yingshan Li on August 8, 2020

Basics of function

Define and call functions

Define function:There are many build-in functions in Python such as print(). However, you can also define your own functions. The basic format to define a new function is:

def 函数名(参数列表):
	函数体

An example:

def sum(a, b):
	return a+b

调用函数:Python内部的很多函数和自己定义的函数都可以直接调用

sum(3, 6)

参数传递

为了让别人和自己方便的调用自己的函数,我们会先把参数的名称和位置确定下来,然后把函数的主题封装起来,这样在调用的时候只需要知道怎么输入参数就可以了。

位置参数: 这是最简单的一种参数形式,上面sum()函数中的a和b就是位置参数,不再赘述

默认参数: 默认参数就是在定义函数的时候就确定了的参数,在调用函数时可传可不传的参数,记住位置参数一定要放在默认参数之前,如果你在调用函数的时候不想用默认的参数,你可以传入自己需要的参数值,举个例子:

def sum(a, b, c=20):
	return a*b+c
	
sum(2, 3)
sum(2, 3, c=10)

关键字参数 如果有的时候参数个数太多,或者你忘记了参数的位置,那么你还可以使用关键字参数,通过“健-值”的方式传入,但前提是你要记住参数的名字。

sum(a=5, b=4)
sum(b=4, a=5)

可变参数 有的函数需要输入的参数个数是可以变的,这个时候就可以定义可变参数。

def func(*args):
	sum = 0
	for i in args:
		sum = sum + i
	return sum

func(2, 5, 10)
func(3, 7)
func()

这里星号*的作用就是将传入的位置参数变成一个tuple,这个tuple是Iterable的,这个过程叫做包裹packing。除了可以包裹位置参数外,还可以包裹关键字参数。

def func(**kw):
	sum = 0
	for value in kw.values():
		sum = sum + value
	return sum

混合使用 当这些不同的参数混合使用时要有一定的顺序:位置参数、默认参数、可变参数

函数式编程

匿名函数

有的时候我们不需要显示的定义一个函数,而可以采用匿名的方式定义,需要用到关键字lamda, 基本语法为:lamda arg: expression

def sum(a, b):
	return(a+b)

func = lambda a, b: a+b 

高阶函数

如果一个函数可以接受另一个函数作为参数,那么这个函数就是高阶函数。

map()

map()函数接受两个参数,一个是函数,一个是可迭代的对象(Iterable),函数依次作用于每一个元素,返回一个迭代器(Iterator)

a = map(lambda x:x^2, range(5))
list(a) #将Iterator变成list打印出来
next(a)

reduce()

reduce()函数也接受两个参数,一个是函数,另一个是Iterable,这个函数先去Iterable对象中的前两个元素作为参数,将输出结果再和下一个元素作为两个参数输入函数,以此类推:

def add(a, b):
	return a+b

reduce(add, range())

filter()

filter()函数和map()函数类似,函数依次作用于每一个元素,判断其真假(True or False),然后根据真或假来决定是保留还是丢弃该元素。

def is_even(n):
	return n%2=0

filter(is_even, range(6))

sorted

基本语法: sorted(iterable, cmp=func1, key=func2, reverse=True/False),基本执行过程就是,cmp()或者key()函数对Iterable中的每个元素处理之后在进行排序,然后对应处理之前的元素返回。

sorted([3, 5, 1, -8, 2], key=abs)
sorted([("a", 2), ("b", 1), ("c", 3)], key=lambda x:x[1])

装饰器

当我们想要给函数添加新的功能但又不想改变函数本身的时候,我们就可以用到装饰器(Decorator),它以需要装饰的函数作为参数,然后输出一个装饰好了的函数。比如我们想让一个函数每次执行的时候都跟你说hello:

def hello(func):
	def wrapper(*args):
		print("hello Yingshan!")
		return func(*args)
	return wrapper

def add(*args):
	sum=0
	for n in args:
		sum = sum + n
	return sum
	
new = hello(add)
new(2, 5, 7)

这个是不加装饰器的过程,但是我们调用的是一个新函数new(),我们调用add()函数的时候不能输出hello,下面是用@添加装饰器之后的版本

def hello(func):
	def wrapper(*args):
		print("hello Yingshan!")
		return func(*args)
	return wrapper

@hello
def add(*args):
	sum=0
	for n in args:
		sum = sum + n
	return sum
	
add(2, 5, 7)

基本的执行过程是,将add函数作为参数传入hello函数,然后输出一个装饰后了的wrapper函数,这样每次调用add的时候其实执行的是wrapper函数,所以add函数传入的参数要和wrapper函数的参数一致,并且add函数经过装饰之后的__name__属性已经不再是add了,而是变成了wrapper。

add.__name__

模块和包

一个python模块就是一个.py文件,一个python包就是包含一个或者多个模块的目录,这个目录可以只有一层,也可以由多层,但是每一层里面必须要有一个__init__.py文件,它里面可以什么都没有。

创建模块

创建一个模块非常简单,下面创建一个叫hello.py的文件

"This is a hello module" #这个就是模块的__doc__属性

__author__ = "Yingshan Li"

def hello():
	print ("Hello Yingshan!")
	
if __name__ == "__main__"
	hello()

上面像__xx__这样的变量是特殊变量,也可以说是模块的属性,__main__的意思是指当模块通过命令行被直接运行时,模块名__name__就不再是文件名了,而是__main__,而只是在python中导入该模块时,模块名还是“hello”,因此不会执行模块中的函数。

###使用模块

  1. “import a” 导入模块:当Python解释器遇到import时,就会按照sys.path的顺序来检索,第一个检索的就是当前目录,所以如果是要导入本地包的话,最好是将包或者模块放在当前目录下面。这个语句只能导入一个简单的模块,对于目录的操作,可以使用sys模块。稍后我们会详细的了解sys模块的使用。

  2. “from a import b”导入包: 你可以从一个模块中导入某一个函数,也可以从一个包中导入某一个模块。

  3. “from a import * “导入全部: 你也可以倒入一个模块或一个包中的所有内容

sys模块中的dic()函数可以查看模块的所有变量,以一个字符串列表返回。当dic()函数没有参数输入是,就会返回当前空间内的所有变量。

常用的标准库模块

sys模块:顾名思义,sys模块可以让我们更方便的的与系统system环境交互,以下是模块中常用的函数:

1) sys.argv: 返回命令行参数列表

2) sys.path: 获取模块检索路径

3) sys.modules.keys(): 返回所有已经导入的模块列表

4) sys.reload(): 当已经导入的模块发生变化后需要重新导入时,可以用这个函数

os模块: 这个模块的名字和sys()模块很像,都是和操作系统交互的,但更偏向于操作系统的文件和目录

1) os.mkdir(): 创建目录 2) os.rmdir(): 删除目录 3) os.remove(): 删除文件 4) os.getcwd(): 获取当前路径 5) os.rename(): 对文件重命名 6) os.chdir(): 更改当前路径 7) os.walk(): 遍历目录,返回含有三个元素的tuple,分别是目录的路径dirpath、目录的名称dirnames、所有文件的名称(第一级目录和所有的子目录)。

datetime、calendar模块:专门处理时间和日期的

re模块: 之间处理字符串的正则表达式工具

math、random、statistics模块:数学模块

互联网访问模块:比如处理URL的urllib.request和stmplib模块