Python必备技巧之函数的使用详解


Posted in Python onApril 04, 2022

1.如何用函数

先定义后调用,定义阶段只检测语法,不执行代码

调用阶段,开始执行代码

函数都有返回值

定义时无参,调用时也是无参

定义时有参,调用时也必须有参

2.默认参数陷阱

2.1针对可变数据类型,不可变不受影响

def c(a=[]):
    a.append(1)
    print(a)
c()
c()
c()

结果:

[1]
[1, 1]
[1, 1, 1]

def c(a=[]):
    a.append(1)
    print(a)
c([])
c([])
c([])

结果:

[1]
[1]
[1]

3.名称空间和作用域

名称空间就是用来存放名字与值内存地址绑定关系的地方(内存空间)

但凡查找值一定要通过名字,访问名字必须去查找名称空间

名称空间分为三大类

内置名称空间: 存放的是python解释器自带的名字

生命周期: 在解释器启动时则生效,解释器关闭则失效

全局名称空间: 存放的是文件级别的名字

生命周期: 在解释器解释执行python文件时则生效,文件执行完毕后则失效

局部名称空间: 在函数内定义的名字

生命周期: 只在调用函数时临时产生该函数的局部名称空间,该函数调用完毕则失效

加载顺序

内置->全局->局部

查找名字的顺序

基于当前所在位置往上查找

假设当前站在局部,查找顺序:局部->全局->内置

假设当前站在全局,查找顺序:全局->内置

名字的查找顺序,在函数定义阶段就已经固定死了(即在检测语法时就已经确定了名字的查找顺序),与函数的调用位置无关

也就是说无论在任何地方调用函数,都必须回到当初定义函数的位置去确定名字的查找关系

作用域: 作用域指的就是作用的范围

全局作用域: 包含的是内置名称空间与全局名称空间中的名字

特点: 全局有效,全局存活

局部作用域: 包含的是局部名称空间中的名字

特点: 局部有效,临时存活

global: 在局部声明一个名字是来自于全局作用域的,可以用来在局部修改全局的不可变类型

nonlocal: 声明一个名字是来自于当前层外一层作用域的,可以用来在局部修改外层函数的不可变类型

4.闭包函数

定义在函数内部且包含对外部函数的作用域名字的引用,需要结合函数对象的概念将闭包函数返回到全局作用域去使用,从而打破函数的层级限制

闭包函数提供了一种为函数体传值的解决方案

def func():
    name='egon'
    def inner():
        print(name)
    return inner
inner = func()
inner()

5.函数的参数

5.1定义阶段

位置形参

在定义阶段从左往右的顺序依次定义的形参

默认形参

在定义阶段已经为其初始化赋值

关键字参数

自由主题

可变长度的形参args

溢出的位置参数,打包成元组,给接受,赋给args的变量名

命名关键字参数

放在*和之间的参数,必须按照key=value形式传值

可变长度的位置形参kwargs

溢出的关键字实参,打包成字典,给**接受,赋给变量kwargs

形参和实参关系: 在调用函数时,会将实参的值绑定给形参的变量名,这种绑定关系临时生效,在调用结束后就失效了

5.2调用阶段

位置实参

调用阶段按照从左往右依次传入的传入的值,会与形参一一对应

关键字实参

在调用阶段,按照key=value形式指名道姓的为形参传值

实参中带*的,再传值前先将打散成位置实参,再进行赋值

实参中带的**,在传值前先将其打散成关键字实参,再进行赋值

6.装饰器:闭包函数的应用

Python必备技巧之函数的使用详解

装饰器就是用来为被装饰器对象添加新功能的工具

**注意:**装饰器本身可以是任意可调用对象,被装饰器的对象也可以是任意可调用对象

为何使用装饰器

**开放封闭原则:**封闭指的是对修改封闭,对扩展开放

6.1装饰器的实现必须遵循两大原则

1. 不修改被装饰对象的源代码`

2. 不修改被装饰器对象的调用方式

装饰器的目标:就是在遵循1和2原则的前提下为被装饰对象添加上新功能

6.2装饰器语法糖

在被装饰对象正上方单独一行写@装饰器的名字

python解释器一旦运行到@装饰器的名字,就会调用装饰器,然后将被装饰函数的内存地址当作参数传给装饰器,最后将装饰器调用的结果赋值给原函数名 foo=auth(foo) 此时的foo是闭包函数wrapper

6.3无参装饰器

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print('from foo')
foo()

6.4有参装饰器

def auth(driver='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

        if driver == 'file':
            if name == 'egon' and pwd == '123':
                print('login successful')
                res=func(*args,**kwargs)
                return res
        elif driver == 'ldap':
            print('ldap')
    return wrapper
return auth2

@auth(driver='file')
def foo(name):
    print(name)

foo('egon')

7.题目

#题目一:
db='db.txt'
login_status={'user':None,'status':False}
def auth(auth_type='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            if login_status['user'] and login_status['status']:
                return func(*args,**kwargs)
            if auth_type == 'file':
                with open(db,encoding='utf-8') as f:
                    dic=eval(f.read())
                name=input('username: ').strip()
                password=input('password: ').strip()
                if name in dic and password == dic[name]:
                    login_status['user']=name
                    login_status['status']=True
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('username or password error')
            elif auth_type == 'sql':
                pass
            else:
                pass
        return wrapper
    return auth2

@auth()
def index():
    print('index')

@auth(auth_type='file')
def home(name):
    print('welcome %s to home' %name)


# index()
# home('egon')

#题目二
import time,random
user={'user':None,'login_time':None,'timeout':0.000003,}

def timmer(func):
    def wrapper(*args,**kwargs):
        s1=time.time()
        res=func(*args,**kwargs)
        s2=time.time()
        print('%s' %(s2-s1))
        return res
    return wrapper


def auth(func):
    def wrapper(*args,**kwargs):
        if user['user']:
            timeout=time.time()-user['login_time']
            if timeout < user['timeout']:
                return func(*args,**kwargs)
        name=input('name>>: ').strip()
        password=input('password>>: ').strip()
        if name == 'egon' and password == '123':
            user['user']=name
            user['login_time']=time.time()
            res=func(*args,**kwargs)
            return res
    return wrapper

@auth
def index():
    time.sleep(random.randrange(3))
    print('welcome to index')

@auth
def home(name):
    time.sleep(random.randrange(3))
    print('welcome %s to home ' %name)

index()
home('egon')

#题目三:简单版本
import requests
import os
cache_file='cache.txt'
def make_cache(func):
    def wrapper(*args,**kwargs):
        if not os.path.exists(cache_file):
            with open(cache_file,'w'):pass

        if os.path.getsize(cache_file):
            with open(cache_file,'r',encoding='utf-8') as f:
                res=f.read()
        else:
            res=func(*args,**kwargs)
            with open(cache_file,'w',encoding='utf-8') as f:
                f.write(res)
        return res
    return wrapper

@make_cache
def get(url):
    return requests.get(url).text


# res=get('https://www.python.org')

# print(res)

#题目四:扩展版本
import requests,os,hashlib
engine_settings={
    'file':{'dirname':'./db'},
    'mysql':{
        'host':'127.0.0.1',
        'port':3306,
        'user':'root',
        'password':'123'},
    'redis':{
        'host':'127.0.0.1',
        'port':6379,
        'user':'root',
        'password':'123'},
}

def make_cache(engine='file'):
    if engine not in engine_settings:
        raise TypeError('egine not valid')
    def deco(func):
        def wrapper(url):
            if engine == 'file':
                m=hashlib.md5(url.encode('utf-8'))
                cache_filename=m.hexdigest()
                cache_filepath=r'%s/%s' %(engine_settings['file']['dirname'],cache_filename)

                if os.path.exists(cache_filepath) and os.path.getsize(cache_filepath):
                    return open(cache_filepath,encoding='utf-8').read()

                res=func(url)
                with open(cache_filepath,'w',encoding='utf-8') as f:
                    f.write(res)
                return res
            elif engine == 'mysql':
                pass
            elif engine == 'redis':
                pass
            else:
                pass

        return wrapper
    return deco

@make_cache(engine='file')
def get(url):
    return requests.get(url).text

# print(get('https://www.python.org'))
print(get('https://www.baidu.com'))


#题目五
route_dic={}

def make_route(name):
    def deco(func):
        route_dic[name]=func
    return deco
@make_route('select')
def func1():
    print('select')

@make_route('insert')
def func2():
    print('insert')

@make_route('update')
def func3():
    print('update')

@make_route('delete')
def func4():
    print('delete')

print(route_dic)


#题目六
import time
import os

def logger(logfile):
    def deco(func):
        if not os.path.exists(logfile):
            with open(logfile,'w'):pass

        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            with open(logfile,'a',encoding='utf-8') as f:
                f.write('%s %s run\n' %(time.strftime('%Y-%m-%d %X'),func.__name__))
            return res
        return wrapper
    return deco

@logger(logfile='aaaaaaaaaaaaaaaaaaaaa.log')
def index():
    print('index')

index()

到此这篇关于Python必备技巧之函数的使用详解的文章就介绍到这了,更多相关Python函数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python中为feedparser设置超时时间避免堵塞
Sep 28 Python
利用Python中的输入和输出功能进行读取和写入的教程
Apr 14 Python
python thrift搭建服务端和客户端测试程序
Jan 17 Python
python得到电脑的开机时间方法
Oct 15 Python
如何使用pyinstaller打包32位的exe程序
May 26 Python
用django-allauth实现第三方登录的示例代码
Jun 24 Python
python 判断字符串中是否含有汉字或非汉字的实例
Jul 15 Python
pycharm配置当鼠标悬停时快速提示方法参数
Jul 31 Python
关于Pytorch MaxUnpool2d中size操作方式
Jan 03 Python
django rest framework serializer返回时间自动格式化方法
Mar 31 Python
Python爬虫定时计划任务的几种常见方法(推荐)
Jan 15 Python
python机器学习实现oneR算法(以鸢尾data为例)
Mar 03 Python
Python批量解压&压缩文件夹的示例代码
Apr 04 #Python
Python调用腾讯API实现人脸身份证比对功能
Python字符串常规操作小结
Anaconda安装pytorch和paddle的方法步骤
python lambda 表达式形式分析
PyTorch device与cuda.device用法
Apr 03 #Python
Python实现为PDF去除水印的示例代码
Apr 03 #Python
You might like
php抽奖小程序的实现代码
2013/06/18 PHP
php版微信公众平台入门教程之开发者认证的方法
2016/09/26 PHP
又一个小巧的图片预加载类
2007/05/05 Javascript
firefox浏览器用jquery.uploadify插件上传时报HTTP 302错误
2015/03/01 Javascript
jQuery+PHP星级评分实现方法
2015/10/02 Javascript
JQuery Mobile 弹出式登录框的实现方法
2016/05/28 Javascript
关于网页中的无缝滚动的js代码
2016/06/09 Javascript
JavaScript实现自定义媒体播放器方法介绍
2017/01/03 Javascript
JS中实现函数return多个返回值的实例
2017/02/21 Javascript
nodejs个人博客开发第五步 分配数据
2017/04/12 NodeJs
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
vue-cli webpack 引入swiper的操作方法
2018/09/15 Javascript
vue-router权限控制(简单方式)
2018/10/29 Javascript
逐行分析鸿蒙系统的 JavaScript 框架(推荐)
2020/09/17 Javascript
JS如何实现在弹出窗口中加载页面
2020/12/03 Javascript
基于vue+echarts数据可视化大屏展示的实现
2020/12/25 Vue.js
利用Python和OpenCV库将URL转换为OpenCV格式的方法
2015/03/27 Python
Python的Flask框架与数据库连接的教程
2015/04/20 Python
python利用正则表达式排除集合中字符的功能示例
2017/10/10 Python
python+tkinter编写电脑桌面放大镜程序实例代码
2018/01/16 Python
使用pandas read_table读取csv文件的方法
2018/07/04 Python
Python正则表达式匹配日期与时间的方法
2019/07/07 Python
python模拟鼠标点击和键盘输入的操作
2019/08/04 Python
python实现对图片进行旋转,放缩,裁剪的功能
2019/08/07 Python
HTML5进度条特效
2014/12/18 HTML / CSS
Coach澳大利亚官方网站:美国著名时尚奢侈品牌
2017/05/24 全球购物
Moda Operandi官网:美国奢侈品电商,海淘秀场T台同款
2020/05/26 全球购物
化学专业毕业生自荐信
2013/11/15 职场文书
报告会主持词
2014/04/02 职场文书
个人剖析材料及整改措施
2014/10/07 职场文书
2014年内勤工作总结
2014/11/24 职场文书
大一学生个人总结
2015/02/15 职场文书
大学生学年个人总结
2015/02/15 职场文书
化妆品促销活动总结
2015/05/07 职场文书
2016党员干部廉洁自律心得体会
2016/01/13 职场文书
Java网络编程之UDP实现原理解析
2021/09/04 Java/Android