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读取注册表中值的方法
Apr 08 Python
用Python从零实现贝叶斯分类器的机器学习的教程
Mar 31 Python
Python 详解基本语法_函数_返回值
Jan 22 Python
Python读取指定目录下指定后缀文件并保存为docx
Apr 23 Python
python初学之用户登录的实现过程(实例讲解)
Dec 23 Python
Python 数据处理库 pandas 入门教程基本操作
Apr 19 Python
解决PyCharm同目录下导入模块会报错的问题
Oct 13 Python
python多线程同步实例教程
Aug 11 Python
python读写csv文件的方法
Aug 13 Python
Django Model中字段(field)的各种选项说明
May 19 Python
Python同时迭代多个序列的方法
Jul 28 Python
Python基础之教你怎么在M1系统上使用pandas
May 08 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基础学习小结
2011/04/17 PHP
将php数组输出html表格的方法
2014/02/24 PHP
ThinkPHP Mobile使用方法简明教程
2014/06/18 PHP
Yii2.0表关联查询实例分析
2016/07/18 PHP
yii框架redis结合php实现秒杀效果(实例代码)
2017/10/26 PHP
分享别人写的一个小型js框架
2007/08/13 Javascript
小试JQuery的AutoComplete插件
2011/05/04 Javascript
javascript数字格式化通用类 accounting.js使用
2012/08/24 Javascript
js去字符串前后空格5种实现方法及比较
2013/04/03 Javascript
关于JS判断图片是否加载完成且获取图片宽度的方法
2013/04/09 Javascript
JavaScript中的数值范围介绍
2014/12/29 Javascript
jQuery mobile转换url地址及获取url中目录部分的方法
2015/12/04 Javascript
jquery二级目录选中当前页的css样式
2016/12/08 Javascript
基于JavaScript实现购物车功能
2017/02/07 Javascript
Bootstrap Multiselect 常用组件实现代码
2017/07/09 Javascript
iview Upload组件多个文件上传的示例代码
2018/09/30 Javascript
Vue列表渲染的示例代码
2018/11/01 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
swiper Scrollbar滚动条组件详解
2019/09/08 Javascript
vue移动端的左右滑动事件详解
2020/06/17 Javascript
JS实现纸牌发牌动画
2021/01/19 Javascript
Vue实现简单计算器
2021/01/20 Vue.js
详解Python迭代和迭代器
2016/03/28 Python
通过5个知识点轻松搞定Python的作用域
2016/09/09 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
2018/04/19 Python
在python中,使用scatter绘制散点图的实例
2019/07/03 Python
解决python中导入win32com.client出错的问题
2019/07/26 Python
tf.concat中axis的含义与使用详解
2020/02/07 Python
django处理select下拉表单实例(从model到前端到post到form)
2020/03/13 Python
python图片验证码识别最新模块muggle_ocr的示例代码
2020/07/03 Python
关于python中remove的一些坑小结
2021/01/04 Python
威尔逊皮革:Wilsons Leather
2018/12/07 全球购物
草莓网中国:StrawberryNet中国
2020/08/17 全球购物
乡镇团代会开幕词
2016/03/04 职场文书
python tkinter模块的简单使用
2021/04/07 Python