码迷,mamicode.com
首页 > 编程语言 > 详细

python-fullstack-s13-day11-python基础

时间:2018-06-14 18:08:44      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:网络   传递   全局   get   closure   FN   www   如何   另一个   

一、函数名的运用

函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量。
1、函数名的内存地址

1 def func():
2     print("呵呵")
3 print(func) # function func at 0x02969C90

2、函数名可以赋值给其他变量

def func():
    print("呵呵")
print(func)
a = func # 把函数当成一个变量赋值给另一个变量
a()    # 函数调用 func()

3、函数名可以当作容器类的元素

 1 def func1():
 2     print("haha1")
 3 def func2():
 4     print("haha2")
 5 def func3():
 6     print("haha3")
 7 def func4():
 8     print("haha4")
 9 lst = [func1,func2,func3,func4] # 列表内存的是函数的内存地址
10 for i in lst:
11     i()

4、函数名可以当作函数的参数

def func():
    print("吃了么")
def func2(fn):
    print("我是func2")
    fn() # 执行传递过来的fn
    print("我是func2")
func2(func)    # 把函数func当成参数传递func2的参数fn

5、函数名可以作为函数的返回值

def func1():
    print("这里是函数1")
    def func2():
        print("这里是函数2")
    print("这里是函数1")
    return func2
fn = func1() # 执行函数1,函数1返回的是函数2,这时fn指向的就是上面的函数2
fn()    # 执行上面返回的函数

二、闭包

什么叫闭包?闭包就是内层函数,对外层函数(非全局)的变量的引用,叫闭包

def func1():
    name = "alex"
    def func2():
      print(name) # 闭包
    func2()
func1()

问题:上课的时候讲的闭包是为了让内存记住一个变量?函数执行完成后海是否能记住这个变量


我们可以使用__closure__来检测函数是否闭包,使用函数名 __closure__返回cell就是闭包,返回None就不是闭包

def func1():
    name = "alex"
    def func2():
        print(name) # 闭包
    func2()
    print(func2.__closure__) # (<cell at 0x03634B90: str object at 0x03424980>,)
func1()  

问题, 如何在函数外边调?内部函数呢?

def outer():
    name = "alex"
    # 内部函数
    def inner():
        print(name)
    return inner
fn = outer() # 访问外部函数, 获取到内部函数的函数地址
fn() # 访问内部函数

# 那如果多层嵌套呢? 很简单, 只需要?层?层的往外层返回就行了

def func1():
    def func2():
        def func3():
            print("嘿嘿")
        return func3
    return func2
func1()()()

闭包的举例:(网络爬虫的应用!)

from urllib.request import urlopen
def but():
    content = urlopen("http://www.xiaohua100.cn/index.html").read()
    def get_content():
        return content
    return get_content
fn = but() # 这个时候就开始加载校花100的内容
# 后?需要?到这??的内容就不需要在执??常耗时的?络连接操作了
content = fn() # 获取内容
print(content)
content2 = fn() # 重新获取内容
print(content2)

三、装饰器初识

编写代码的开闭原则:对功能扩展开放,修改代码封闭。可以对原有代码增加相应的功能但是不能修改代码

装饰器版本

def create_people():
    print("女娲很厉害,捏个泥人吹口气就成了人!")
# create_people()

def water(fn):
    def inner():
        print("先浇水")
        fn()
        print("施肥")
    return inner
# func = water(create_people)
# func()
create_people = water(create_people) # 函数名和变量名一样,可以赋值给其他变量
create_people()

带语法糖的版本

@water
def create_people():
    print("女娲很厉害,捏个泥人吹口气就成了人!")
# create_people()

def water(fn):
    def inner():
        print("先浇水")
        fn()
        print("施肥")
    return inner
# func = water(create_people)
# func()
# create_people = water(create_people) # 函数名和变量名一样,可以赋值给其他变量
create_people()

注:可以理解为重新写一个函数,这个函数将原函数包装在最里部

也就是将需要增加功能的函数包装在def/def inner 代码块中

python-fullstack-s13-day11-python基础

标签:网络   传递   全局   get   closure   FN   www   如何   另一个   

原文地址:https://www.cnblogs.com/bug-ming/p/9183412.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!