python函数简介

函数的基础概念

函数是python为了代码最大程度地重用和最小代码冗余而提供的基本数据结构。 函数是一种设计工具,可能将复杂的程序,分解成可以管理的块。

在python中可以创建四种函数:

  • 全局函数:定义在模块中
  • 局部函数:嵌套在其他函数中
  • lambda函数:表达式
  • 方法:与特定数据类型关联的函数,并且只能与数据类型关联一起使用。

创建函数

语法

def functionName(parameters)
    suite

函数的调用形式:

  • 语句形式:

    func()

  • 表达式形式:

    res = func2(10)

  • 函数当另一个函数的参数传入一个函数调用:

    res = func3(func2(10))

函数的作用域:

python创建、改变或者查找变量名都是在名称空间进行

在代码中变量名被赋值的位置决定了其能被访问到的范围

函数定义了本地作用域,而模块定义了全局作用域

每个模块都是一个全局作用域,因此全局作用域仅限单个程序文件。

每次对函数的调用都会创建一个新的本地作用域,赋值的变量除非声明为全局变量,否则均为本地变量。

所有的变量名都可以归纳为本地、全局或者内置的变量。

内置名称空间:python解释器自带的名字,python解释器启动就会生成。

全局名称空间:文件和模块级别定义的名字都会。

局部名称空间:定义在函数内部的名字。局部名称空间只有在函数调用时才会生效,调用结束失效。

变量名解析:LEGB原则,作用域越小优先级越高,某个变量,现在本地函数找,找不到去上一层函数找,再找不到就去模块全局变量找,再找不到就去系统内置的变量找,最后还是内找不到,抛出异常。

LEGB原则:

备注:

global定义全局变量,可以在函数内部改变函数外面定义的全局变量的赋值

locals局部作用域,可以改变函数内变量赋值,无论函数内套多少层函数。

函数的嵌套

语法

函数的嵌套定义

def f1():
            def f2():
                def f3():
                    print(‘from f3‘)
                f3()
            f2()

        f1()

备注:函数嵌套可以进行多层嵌套


python参数的匹配模型

传递参数的方式:

第一种:通过位置,精确匹配参数个数进行从左至右传递参数。

In [26]: def f1(x,y):
   ....:     print(x,y)
   ....:     

In [27]: f1(1,2)
1 2

第二种:通过关键字明确指定参数

In [26]: def f1(x,y):
   ....:     print(x,y)
   ....:     

In [28]: f1(y=1,x=2)
2 1

混用上面两种方式时:所有位置参数先写,所有的关键字参数可以不按顺序写。

In [29]: def f1(x,y,z):
   ....:     print(x,y,z)
   ....:     

In [30]: f1(1,z=3,y=2)
1 2 3

可以给个默认参数,如果不传递参数,就启用默认参数。

In [32]: def f1(x,y,z=3):
    print(x,y,z)
   ....:     

In [33]: f1(1,2)
1 2 3

可变参数:

定义的时候*可以收集多个位置参数,表现形式是元组

In [34]: def f2(*x):
   ....:     print(x)
   ....:     

In [35]: f2(1,2,3)
(1, 2, 3)

**可以收集多个关键字参数,表现形式是字典。

In [36]: def f2(**x):
    print(x)
   ....:     

In [37]: f2(x=1,y=2,z=3)
{‘x‘: 1, ‘y‘: 2, ‘z‘: 3}

闭包函数

内部函数包含对外部作用域而非全局作用域的引用

闭包函数的特点:

  • 自带作用域
  • 延迟计算

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

例子:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果

from urllib.request import urlopen

def index(url):
    def get():
        return urlopen(url).read()
    return get
pa360 = index(‘https://hao.360.cn/?src=bm‘)

print(pa360())

函数装饰器

  • 装饰器本身是一个函数,用于装饰其它函数
  • 增强被装饰函数的功能。
  • 装饰器一般接受一个函数作为参数,以对其进行增强。

语法: 被装饰函数的正上方使用@装修器名称,单独一行。

@deco1
def func1():
        pass

例子:编写装饰器,为函数加上统计时间的功能

import time
import random
from functools import wraps
def time1(func):
    def time2():
        ‘time2‘
        start_time = time.time()
        func()
        stop_time =time.time()
        print(‘run time is %s‘%(stop_time-start_time))
    return time2

@time1
def func1():
    ‘func1‘
    time.sleep(random.randrange(1,5))
    print(‘welecome to func1‘)

例子:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码 # 注意:从文件中读出字符串形式的字典,可以用eval(‘{"name":"egon","password":"123"}‘)转成字典格式

user_d1 = {
    ‘gangdan‘:‘123‘,
    ‘laowang‘:‘123‘,
    ‘xiaoming‘:‘123‘
}

with open(‘db.txt‘,‘w‘,encoding=‘utf-8‘) as f:
    f.write(str(user_d1))
login_d1 = {‘user‘:None,‘status‘:False }
db_path =r‘db.txt‘

def fauth(func):
    def auth(*args,**kwargs):
        if login_d1[‘user‘] and login_d1[‘status‘]:  #这个地方如果没有登录成功None第一行就执行不成功。
            res = func(*args,**kwargs)
            return res
        user = input(‘input user :‘)
        passwd = input(‘input passwd :‘)
        with open(db_path, ‘r‘, encoding=‘utf-8‘) as f:
            user_d2 = eval(f.read())
        if user in user_d2 and passwd == user_d2[user]:
            print(‘login ok‘)
            login_d1[‘user‘] = user
            login_d1[‘status‘] = True
            res = func(*args,**kwargs)
            return res
        else:
            print(‘login error‘)
    return auth

@fauth
def fucn1():
    print(‘welecome to func1‘)

@fauth
def func2(name):
    print(‘welecome to func2‘)

fucn1()
func2(‘gangdan‘)

例子:编写装饰器,实现缓存网页内容的功能:

from urllib.request import urlopen
import  os
file_path = r‘url.txt‘
def cache(func):
    def wrapper(*args,**kwargs):
        if os.path.getsize(file_path):
            with open(file_path,‘rb‘) as f:
                res = f.read()
                print(‘从缓存文件下载‘)
        else:
            res = func(*args,**kwargs)()
            with open(file_path,‘wb‘) as f:
                f.write(res)
                print(‘从网站下载‘)
        return res
    return wrapper

@cache
def url1(url):
    def get(*args,**kwargs):
        return urlopen(url).read()
    return get

print(‘第一下载‘)
print(url1(‘https://www.baidu.com/‘))

print(‘第二下载‘)
print(url1(‘https://www.baidu.com/‘))

print(‘第三下载‘)
print(url1(‘https://www.baidu.com/‘))

例子:还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,

# 在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作

func_dic = { }
def deco (key):
    def deco2(func):
        func_dic[key] = func
    return deco2

@deco(‘f1‘)  #  f1= deco2(f1)  dec2(f1)执行后就是把‘f1‘:‘f1函数内存地址加进字典‘
def f1():
    print(‘from f1‘)
@deco(‘f2‘)  #  f2= deco2(f2)  dec2(f2)执行后就是把‘f2‘:‘f2函数内存地址加进字典‘
def f2():
    print(‘from f2‘)
@deco(‘f3‘)   #  f3= deco2(f3)  dec2(f3)执行后就是把‘f3‘:‘f3函数内存地址加进字典‘
def f3():
    print(‘from f3‘)

print(func_dic)

while True:
    cmd = input(‘>>: ‘).strip()
    if cmd == ‘q‘:
        break
    if cmd in func_dic:
        func_dic[cmd]()

生成器

生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行

生成器函数优点:

1.是可迭代对象

2.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处。

例子:编写实现tail -f a.txt |grep ‘error‘ |grep ‘404‘命令函数,使用生成器函数。

import time
def tail(file_path,encodimg=‘utf-8‘):
    with open(file_path,encoding=encodimg) as f:
        f.seek(0,2)
        while True:
            line = f.readline()
            if line:
                yield line
            else:
                time.sleep(0.3)

def grep(lines,pattern):
    for line in lines:
        if pattern in line:
            yield line

g1 = tail(‘a.txt‘)
g2 = grep(g1,‘error‘)
g3 = grep(g2,‘404‘)
for i in g3:
    print(i)

协程函数

除了可以使用 next()方法来获取下一个生成的值,用户还可以使用 send()方法将一个新的或者是被修改的值返回给生成器。第一个值必须初始化,才能使用send进行传值。

例子:

def init(func):   #初始化装饰器
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        next(res)
        return res
    return wrapper

@init
def eater(name):
    print(‘%s ready to eat‘%name)
    food_list = [ ]
    while True:
        food = yield food_list   #使用yield 表达式模式进行传值
        food_list.append(food)
        print(‘%s start to eat %s‘%(name,food))

g = eater(‘alex‘)
print(g.send(‘饺子‘))

面向过程编程

"面向过程编程"(Procedure Oriented)是一种以过程为中心的编程思想,就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。整个过程就相当于一条生产的流水线。

例子:运用过程式编程:模拟grep -rl 功能:

import os
def init(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        next(res)
        return res
    return wrapper
#阶段一:递归地找文件的绝对路径,把路径发给阶段二
@init
def search(target):
    ‘sear file abspath‘
    while True:
        start_path = yield
        g = os.walk(start_path)
        for par_dir,_,files in g:
            for file in files:
                file_path = r‘%s\%s‘ % (par_dir,file)
                target.send(file_path)

# 阶段二:收到文件路径,打开文件获取对象,把文件对象发给阶段三
@init
def opener(target):
    ‘get file obj: f = open(filepath)‘
    while True:
        file_path = yield
        with open(file_path,encoding=‘utf-8‘) as f:
            target.send((file_path,f))

# 阶段三:收到文件对象,for循坏读取文件的每一行内容,把每一行内容发给阶段四。
@init
def cat(target):
    ‘read file‘
    while True:
        filepath ,f = yield
        for line in f:
            res = target.send((filepath,line))
            if res:
                break

# 阶段四:收到一行内容,判断root是否在一行中,如果在,则把文件名发给阶段五
@init
def grep(target,pattern):
    ‘grep function‘
    tag = False
    while True:
        filepath,line = yield tag
        tag = False
        if pattern in line:
            target.send(filepath)
            tag = True

#阶段五:收到文件名,打印结果
@init
def printer():
    ‘print function‘
    while True:
        filepath = yield
        print(filepath)

start_path = r‘E:\py_code\py_s5\py_s5\day11\a‘
g = search(opener(cat(grep(printer(),‘root‘))))
g.send(start_path)
时间: 2024-10-12 16:23:04

python函数简介的相关文章

python 函数简介之三

1. 非固定个数的实参----参数组,* args ,其结果将以元组的形式呈现出来 def func(*args): print(args) func(1,2,3,4,5) #第一种调用方式, 多个实参 func(*[1,2,3,4,5]) #第二种调用方式, 将以*[] 的形式调用 #运行结果 (1, 2, 3, 4, 5) (1, 2, 3, 4, 5) 2. 固定个数实参,参数组, 二者结合  (a, *args) def func2(x,*args): print(x,args) fun

Python的简介与入门

Python的简介与入门 ·Python是一种结合了解释.性编译性.互动性和面向对象多种特性的脚本语言.对于编程初学者而言,Python易于阅读与学习,并且支持广泛的应用程序的开发与拥有支持多种平台的广泛的基础数据库. ·安装Python在Windows环境下  1.进入Python 官方网站:https://www.python.org/                 2.点击Downloads==> Downloads for Windows==> Python 3.6.2  3.下载安

以写代学:python 模块简介&输出用户指定位数密码的脚本

什么是模块 (1)模块是从逻辑上组织python代码的形式 (2)当代码量变的相当大的时候,最好把代码分成一些有组织的代码段,前提是保证它们的彼此交互 (3)这些代码段之间有一定的联系,可能是一个包含数据成员和方法的类,也可能是一组相关但彼此独立的操作函数 (4)模块名不能乱起,字母数字下划线组成,首字母不能是数字 导入模块 (1)使用import导入模块,模块被导入后,程序会自动生成pyc的字节码文件以提升性能 (2)模块属性通过"模块名.属性"的方法调用,如果仅需要模块中的某些属性

4.python函数基础

一.函数 1.函数简介 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函数,这被叫做用户自定义函数. 例如: 不用函数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 while True:     if cpu利用率 > 90%:         #发送邮件提醒         连接邮箱服务器       

Python的简介以及安装和第一个程序以及用法

Python的简介: 1.Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.自从20世纪90年代初Python语言诞生至今,它逐渐被广泛应用于处理系统管理任务和Web编程.Python已经成为最受欢迎的程序设计语言之一.2011年1月,它被TIOBE编程语言排行榜评为2010年度语言.自从2004年以后,python的使用率是呈线性增长. 2.Python在设计上坚持了清晰划一的风格,Python的作者有意的设计限制性很强的语法,使得不好的编程习惯(例如if语句的下一行不向右缩

浅析python函数

慢慢的开始进入状态啦,被明老师说我什么都不会后我觉得是该反思下自己这个学期的学习了,虽然我对实验没有很大的兴趣,但是既然名老师要求我开始做实验,我就跟着小丹师姐好好学学,用Tanger师兄的话来说就是:做实验有利于你理解生物信息学数据处理的原理,也许有一天,未来做生物信息的学弟学妹会看到这段话,就像我在码迷上看到free_mao的博文一样,生物信息还是基于生物的,生物原理必须要理解,不然和做计算机有什么区别呢?以前对书本的知识不够重视,语言的学习进度很缓慢,现在希望能分享一些学习心得体会给大家,

python函数

python函数学习 1. 概述: 函数是重用的程序段,用关键字def来定义,可以任意多次地运行这个语句块,被称为调用函数.Python提供了许多内建函数,比如print(),也可以自己创建函数,这被叫做用户自定义函数,函数能提高应用的模块性,和代码的重复利用率. 2.函数语法: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号(). 任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数. 函数的第一行语句可以选择性地使用文档字符串-用于存放函数说明. 函数内容以冒号起

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

python 函数

函数的定义 函数最重要的目的是方便我们重复使用相同的一段程序. 将一些操作隶属于一个函数,以后你想实现相同的操作的时候,只用调用函数名就可以,而不需要重复敲所有的语句. 创建函数 def 函数名 (参数列表) 函数体 例如: def sum1(a,b): c = a + b return c e=1 f=2 print (sum1(e,f)) 首先def 是定义函数名 sum1是函数名 括号中的a, b是函数的参数,是对函数的输入.参数可以有多个,也可以完全没有(但括号要保留). c = a +