python基础(3):函数对象、函数嵌套、名称空间与作用域、装饰器

  1. 函数对象

  2. 函数嵌套

  3. 名称空间与作用域

  4. 闭包函数

  5. 装饰器

  6. 练习

一 函数对象

#1 可以被引用
def max(x, y):
    return x if x > y else y
func = max
print(func(1, 2))

#2 可以当作参数传递
def max(x, y):
    return x if x > y else y
def max_1(x, func):
    return func(x, 1)
print(max_1(2, max))

#3 返回值可以是函数

#4 可以当作容器类型的元素
def foo():
    print(‘foo‘)

def bar():
    print(‘bar‘)

dic={
    ‘foo‘:foo,
    ‘bar‘:bar,
}
while True:
    choice=input(‘>>: ‘).strip()
    if choice in dic:
        dic[choice]()

二 函数嵌套

def foo():
    def bar():
        print(‘from bar‘)
    bar()

foo()bar() #报错

三 名称空间与作用域

#名称空间:存放名字的地方,(x=1,1存放于内存中,名称空间正是存放名字x与1绑定关系的地方)
#三种名称空间:局部名称空间--->全局名称空间--->内置名称空间

内置名称空间在 Python 解释器启动时就创建了,直到 Python 解释器退出时内置名称空间才失效。这使得我们可以在程序的任何位置使用内置名称空间内的名称,例如,id()print()等函数。 全局命名空间,每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量。python自带的内建命名空间,任何模块均可以访问,放着内置的函数和异常。
#1、作用域即范围
        - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
      - 局部范围(局部名称空间属于该范围):临时存活,局部有效
#2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
x=1
def f1():
    def f2():
        print(x)
    return f2
x=100
def f3(func):
    x=2
    func()
x=10000
f3(f1())

#3、查看作用域:globals(),locals()

LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间

四 闭包函数

它是怎么产生的及用来解决什么问题呢。给出字面的定义先:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)

def counter():
    n = 0

    def incr():
        nonlocal n
        x = n
        n += 1
        return x

    return incr

c = counter()
print(c())
print(c())
print(c.__closure__[0].cell_contents)  # 查看闭包的元素

用途:延迟计算

from urllib.request import urlopen

def index(url):
    def get():
        return urlopen(url).read()

    return get

baidu = index(‘http://www.baidu.com‘)
print(baidu().decode(‘utf-8‘))

五 装饰器

装饰器就是闭包函数的一种应用场景,用于拓展原来函数功能的一种函数

强调装饰器的原则:1 不修改被装饰对象的源代码  2 不修改被装饰对象的调用方式

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

装饰器函数以目标函数名为参数,且必须返回一个函数调用目标函数参数执行

import time

def deco1(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        print(‘deco1 start‘)
        func(*args, **kwargs)
        print(‘deco1 end‘)
        end_time = time.time()
        print(end_time - start_time)
    return wrapper

def deco2(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        print(‘deco2 start‘)
        func(*args, **kwargs)
        print(‘deco2 end‘)
        end_time = time.time()
        print(end_time - start_time)
    return wrapper

@deco1
@deco2
def fun(x, y):
    time.sleep(2)
    print(x + y)

fun(1, 2)

装饰器函数的参数为被装饰函数。装饰后执行被装饰函数相当于执行装饰器函数返回的函数,即例子中的wrapper

六 练习

# 编写函数,函数执行的时间是随机的
import random
import time
def func1():
    t = random.random()
    print(‘sleeping time =‘, t)
    print(‘sleeping starts‘)
    time.sleep(t)
    print(‘sleeping ends‘)
func1()
# 编写装饰器,为函数加上统计时间的功能
import random
import time

def deco(func):
    def wrapper(*args, **kwargs):
        stime = time.time()
        func(*args, **kwargs)
        etime = time.time()
        print(‘deco time:‘, (etime - stime))
    return wrapper

@deco
def func():
    t = random.random()
    print(‘sleeping time =‘, t)
    print(‘sleeping starts‘)
    time.sleep(t)
    print(‘sleeping ends‘)

func()
# 编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录
# db.txt内容:{‘user‘: ‘zsy‘, ‘passwd‘: ‘123‘}
db = ‘db.txt‘

def auth(authtype=‘file‘):
    user_status = {‘user‘: None, ‘passwd‘: None}
    def origin_auth(func):
        def wrapper(*args, **kwargs):
            if authtype == ‘file‘:
                if user_status[‘user‘] != None or user_status[‘passwd‘] != None:
                    func(*args, **kwargs)
                else:
                    dict = eval(open(db, ‘r‘, encoding=‘utf-8‘).read())
                    user_name = input(‘Name: ‘)
                    user_passwd = input(‘Passwd: ‘)
                    if user_name == dict[‘user‘] and user_passwd == dict[‘passwd‘]:
                        user_status[‘user‘] = user_name
                        user_status[‘passwd‘] = user_passwd
                        print(‘登录成功‘)
                        func(*args, **kwargs)
                    else:
                        print(‘用户名或密码错误‘)
            elif authtype == ‘sql‘:
                print(‘暂无sql库‘)
            else:
                print(‘错误的authtyoe‘)
        return wrapper
    return origin_auth

origin_auth = auth()
@origin_auth
def func():
    print(‘func‘)

func()

@origin_auth
def func2():
    print(‘func2‘)

func2()
# 编写装饰器,实现缓存网页内容的功能:
具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中

import os, requests, hashlib
engine_conf = {
    ‘file‘: {‘dirname‘: ‘db‘},
    ‘sql‘: {
        ‘host‘: ‘127.0.0.1‘,
        ‘port‘: 3306,
        ‘user‘: ‘root‘,
        ‘password‘: ‘123‘},
    ‘redis‘: {
        ‘host‘: ‘127.0.0.1‘,
        ‘port‘: 6379,
        ‘user‘: ‘root‘,
        ‘password‘: ‘123‘}
}

db = ‘db.txt‘

def make_cache(engine = ‘file‘):
    if engine not in engine_conf:
        raise TypeError(engine + ‘ not in engine_conf‘)
    user_status = {‘user‘: None, ‘passwd‘: None}
    def deco(func):
        if user_status[‘user‘] == None or user_status[‘passwd‘] == None:
            user_info = eval(open(db, ‘r‘).read())
            user_name = input(‘User: ‘)
            user_passwd = input(‘Passwd: ‘)
            if user_name != user_info[‘user‘] or hashlib.md5(user_passwd.encode(‘utf-8‘)).hexdigest() != user_info[‘passwd‘]:
                print(‘用户名或密码错误‘)
                exit()
            else:
                user_status[‘user‘] = user_name
                user_status[‘passwd‘] = user_passwd
        def wrapper(url):
            if engine == ‘file‘:
                filename = hashlib.md5(url.encode(‘utf-8‘)).hexdigest()
                filepath = os.path.join(engine_conf[‘file‘][‘dirname‘], filename)
                if os.path.exists(filepath):
                    print(‘已爬取该网页‘)
                else:
                    content = func(url)
                    if content == None:
                        print(‘爬取内容为空‘)
                    else:
                        with open(filepath, ‘w‘, encoding=‘utf-8‘) as f:
                            f.write(content)
            elif engine == ‘sql‘:
                pass
            elif engine == ‘redis‘:
                pass
        return wrapper
    return deco

@make_cache()
def get_html_text(url, *args, **kwargs):
    try:
        response = requests.get(url)
        response.encoding = response.apparent_encoding
        response.raise_for_status()
        return response.text
    except:
        return None

get_html_text(‘http://www.baidu.com‘)

原文地址:https://www.cnblogs.com/zhangshuyuan/p/9571592.html

时间: 2024-08-07 00:26:07

python基础(3):函数对象、函数嵌套、名称空间与作用域、装饰器的相关文章

函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数def max(x,y): if x>y: return x else: return ydef max1(a,b,c,d): res=max(a,b) res2=max(res,c) res3=ma

python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式

本节课重要知识点内容如下: 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式 1.函数嵌套 函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数 def bar(): print('from nbar')def foo(): print('from foo') bar()foo()def max2(x,y): if x > y: return x else: return ydef max4(a,

函数对象,函数的嵌套,名称空间与作用域,闭包,装饰器,迭代器,内置函数

一,函数对象 函数对象:函数是第一类对象,即函数可以当做数据传递 1,可以被引用 2,可以做参数的传递 3,返回值可以是函数 4,可以当作容器类型的元素 二,函数嵌套 1,函数的嵌套调用 2,函数的嵌套定义 三,名称空间与作用域 名称空间:存放名字的地方叫名称空间,存放这些值与名字的绑定关系 查看内置名称的两种方法: 三种名称空间 1,内置名称空间:随着python解释器的启动而产生 2,全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入该空间 3,局部名称空间:调用函

Python全栈__动态参数、名称空间、作用域、作用域链、加载顺序、函数的嵌套、global、nonlocal

1.动态参数 当实参数量与形参数量相等时,参数传递正常. def func1(a, b, c): pass func1(1, 2, 3) 当实参数量与形参数量不相等时,则会报错. def func1(a, b, c): pass func1(1, 2, 3, 4, 5, 6, 6) 用户传入到函数中的实参数量不确定时,或者为了以后扩展,此时要用到动态参数 *args  **kwargs(万能参数). 顺序: 位置参数,*args,默认参数,**kwargs 1.*args *args是接收的是所

函数参数补充、名称空间与作用域、global与nonlocal

函数参数补充 # 1. 命名关键字参数(了解)# 命名关键字参数:在定义函数时,*后定义的参数,如下所示,称之为命名关键字参数# 特点:# 1.命名关键字实参必须按照key=value的形式为其传值# def func(x,y,*,a,b): # 其中,a和b称之为命名关键字参数# print(x,y)# print(a,b)## # func(1,2,b=222,a=111) # 示例# def func(x,y,*,a=11111,b):# print(x,y)# print(a,b)##

python基础之====函数对象、函数嵌套、名称空间与作用域、装饰器

阅读目录 一 函数对象 二 函数嵌套 三 名称空间与作用域 四 闭包函数 五 装饰器 六 练习题 一 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if def foo(): print('foo') def bar(): print('bar') dic={ 'foo':foo, 'bar':bar, } while True: choice=input(

函数基础之对象,嵌套,名称空间和作用域

函数对象 函数名和变量名是等同的 引用 函数的参数 函数的返回值 容器类元素 函数的嵌套 def f1(): def f2(): pass 函数的调用 def f1(): pass f1() def f2(): f1() # 函数必须得先定义后调用 名称空间与作用域 内置名称空间 Python解释器的内置方法,如 len/int/float, python解释器启动的时候就有了 全局名称空间 python文件执行的时候生成 局部名称空间 函数调用的时候生成 执行顺序 内置-->全局-->局部

python基础之名称空间和作用域、函数嵌套

一.名称空间 1.定义:存放名字与值的绑定关系 2.名称空间分为:内置名称空间.全局名称空间.局部名称空间 内置名称空间:python解释器自带的名字,python解释器启动就会生成 全局名称空间:文件级别定义的名字都会存放与全局名称空间,执行python文件时会产生 局部名称空间:定义在函数内部的名字,局部名称空间只有在调用函数时才会生效,函数调用结束则失效 3.加载的顺序:三者的加载顺序:内置名称空间->全局名称空间->局部名称空间 4.取值的顺序:局部名称空间->全局名称空间-&g

python之旅:函数对象、函数嵌套、名称空间与作用域、装饰器

一.函数对象 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 # 利用该特性,优雅的取代多分支的if 二.函数嵌套 三.名称空间与作用域 四丶装饰器 原文地址:https://www.cnblogs.com/moyand/p/8667266.html