前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬虫 (二十四) 或许这样认识 python 函数会更有趣 (十五)

爬虫 (二十四) 或许这样认识 python 函数会更有趣 (十五)

作者头像
公众号---人生代码
发布2020-01-13 16:42:43
3880
发布2020-01-13 16:42:43
举报
文章被收录于专栏:人生代码人生代码

长文预警 阅读约 5 分钟

相信如果你慢慢把这篇文章读完,然后加以实践,你会对 python 函数会有很大的理解,加油看完哦

经过上面三节,穿插讲了一下 HTTP 的知识点,以及浏览器的界面资源的获取,以及运行过程,我们可以收获到很多东西,如果没有好好看的伙伴可以趁热打铁

客户端浏览器一次http完整请求过程流程图(图文结合诠释请求过程)

网络基础HTTP协议进化篇

网络基础意淫篇

作为一个Python的初学者来说,深入理解Python中函数的概念是一件重要的事情。

重点1:如何理解函数是第一类对象(一等公民) 函数是第一类对象的概念:

第一:函数的名字是对函数的引用

第二:函数作为第一类对象可以赋值给其他的变量

第三:可以作为函数的参数传递给其他的函数

第四:可以作为函数的返回值

第五:函数可以作为容器类型的一个元素

简单来说,在python当中,函数可以当做数据来进行传递,即变量有什么特性,函数就有什么特性。函数名字实际上就是一个指针变量,里面存放着函数体内存空间的地址

代码语言:javascript
复制
def foo():
    """
    关键:foo就是C语言当中的指针变量,里面存放着内存空间的地址
    """
    print('我爱吃大刀肉')
    print('我爱吃涮羊肉')
    print('我爱吃土豆肉')

fun = foo
print(fun,foo)
#此时此刻fun和foo这两个指针变量指向同一块的内存空间
fun()
代码语言:javascript
复制
def foo():
    """
    关键:foo就是C语言当中的指针变量,里面存放着内存空间的地址
    """
    print('我爱吃大刀肉')
    print('我爱吃涮羊肉')
    print('我爱吃土豆肉')

def g(func):
    #我们将func作为一个函数的参数进行传递
    print(func)
    func()

g(foo)
代码语言:javascript
复制
def foo():
    """
    关键:foo就是C语言当中的指针变量,里面存放着内存空间的地址
    """
    print('我爱吃大刀肉')
    print('我爱吃涮羊肉')
    print('我爱吃土豆肉')

def g(func):
    #我们将func作为函数的返回值进行使用
    print(func)
    return func

f = g(foo)
print(f)
f()

接下来我们将对最后一个进行深入讲解:

示例1:普通版程序

代码语言:javascript
复制
def select(sql):
    print('=========>select')

def insert(sql):
    print('=========>insert')

def update(sql):
    print('=========>update')

def delete(sql):
    print('=========>delete')


if __name__ == '__main__':
    while True:
        sql = input('>>').strip()
        if not sql:continue
        l = sql.split()
        cmd = l[0]
        if cmd == 'select':
            select(sql)
        elif cmd == 'insert':
            insert(sql)
        elif cmd == 'update':
            update(sql)
        elif cmd == 'delete':
            delete(sql)
        else:
            pass

上面的这个程序看似没有什么问题,但是如果有20个类型的话,难道你要写20个if....else...吗?

修改版:

代码语言:javascript
复制
def select(sql):
    print('=========>select')

def insert(sql):
    print('=========>insert')

def update(sql):
    print('=========>update')

def delete(sql):
    print('=========>delete')


if __name__ == '__main__':
    #作为第一类对象,函数可以作为容器类型的元素
    dict_func = {
        'select':select,
        'insert':insert,
        'update':update,
        'delete':delete,
    }

    while True:
        sql = input('>>').strip()
        if not sql:continue
        l = sql.split()
        cmd = l[0]
        if cmd in dict_func:
            dict_func[cmd](sql)

经过上面一折腾,是不是代码上升了一个档次。

实际业务版:普通版程序

代码语言:javascript
复制
def handle_async(tag_id,tag_type):
    """
    :param tag_id: DDL id
    :param tag_type: 具体类型
    content:if...else...后续这里要继续优化
    """
    if '数据库自助化上线' in tag_type:
        handle_service(tag_id,tag_type)
    elif '普通上线申请流程' in tag_type:
        handle_common(tag_id, tag_type)
    elif '空库初始化' in tag_type:
        handle_empty(tag_id, tag_type)
    elif 'DBChange确认流程' in tag_type:
        handle_dbchange(tag_id, tag_type)
    elif 'DDL变更申请流程' in tag_type:
        handle_ddl(tag_id, tag_type)
    else:
        pass

改进版:

代码语言:javascript
复制
def handle_async(tag_id,tag_type):
    dict_func = {
       '数据库自助化上线':handle_service,
       '普通上线申请流程':handle_common,
       '空库初始化':handle_empty,
       'DBChange确认流程':handle_dbchange,
       'DDL变更申请流程':handle_ddl,
    }

    for key in dict_func:
        if key in tag_type:
            dict_func[key](tag_id,tag_type)

后来因为代码我又改了一次:普通版如下

代码语言:javascript
复制
def handle_async(tag_id,tag_type):
    """
    :param tag_id: DDL id
    :param tag_type: 具体类型
    content:if...else...后续这里要继续优化
    """
    if '数据库自助化上线' in tag_type:
        url = url_list['service'] + tag_id
        handle_service(tag_id,tag_type,url=url)
    elif '普通上线申请流程' in tag_type:
        url = url_list['common'] + tag_id
        handle_common(tag_id, tag_type,url=url)
    elif '空库初始化' in tag_type:
        url = url_list['empty'] + tag_id
        handle_empty(tag_id, tag_type,url=url)
    elif 'DBChange确认流程' in tag_type:
        handle_dbchange(tag_id, tag_type)
    elif 'DDL变更申请流程' in tag_type:
        url = url_list['ddl'] + tag_id
        handle_ddl(tag_id, tag_type,url=url)
    else:
        pass

改进版如下:

代码语言:javascript
复制
def handle_async(tag_id,tag_type):
    dict_func = {
       '数据库自助化上线':['service',handle_service],
       '普通上线申请流程':['common',handle_common],
       '空库初始化':['empty',handle_empty],
       'DBChange确认流程':['dbchange',handle_dbchange],
       'DDL变更申请流程':['ddl',handle_ddl],
    }

    for key,value in dict_func.items():
        if key in tag_type:
            url = url_list[item[0]]+tag_id
            item[1](tag_id,tag_type,url=url)

OK,基本上就是这么一个套路。

重点2:函数的嵌套

函数嵌套调用和嵌套定义的概念:

函数的嵌套调用:在一个函数的内部调用另外一个函数,叫做函数的嵌套调用

函数的嵌套定义:在一个函数的内部定义另外一个函数,叫做函数的嵌套定义

示例程序1:

代码语言:javascript
复制
def max2(x1,x2):
    max_value =  x1 if x1 > x2 else x2
    return max_value


def max4(x1,x2,x3,x4):
    x12 = max2(x1,x2)
    x34 = max2(x3,x4)
    max_value = x12 if x12 > x34 else x34
    return max_value


print(max4(130,20,30,40))

示例程序2:

代码语言:javascript
复制
def fun1():
    """
    contention:函数的定义相当于变量的定义,是没有任何实际打印效果的
    """
    print('大刀肉....')
    def fun2():
        print('涮羊肉....')
        def fun3():
            print('土豆肉....')
        fun3()
    fun2()


fun1()

重点3:Python中名称空间与作用域的概念

在python当中,名称空间与作用域是一个比较难理解的概念,希望在这里给大家讲清楚。

名称空间与作用域的概念:

名称空间:描述的就是名字与数值的绑定关系,可以理解为存放名字(标识符)的地方;作用域:名字起作用的区域,范围

注意:

1、名称空间与名称空间彼此之间是互相隔离的

2、不同namespace的创建/销毁时间也不同

3、两个不同namespace中的两个相同名字的变量之间没有任何联系

Python中名称空间的分类:

在Python当中,名称空间分为3种:局部名称空间(locals)、全局名称空间(globals)和内置名称空间(builtins)

局部名称空间:即在函数内部定义的名称空间,包括局部变量和形式参数以及在函数内部定义的函数

全局名称空间:即在文件级别定义的名称空间,在文件级别定义的名字都会放入该空间

内置模块的名称空间:builtins

简单来说:

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

全局名称空间:存文件级别定义的名字

内置名称空间:存内置的名字

Python中名称空间的加载顺序以及名字的查找顺序:

加载顺序:

内置模块的名称空间====>全局名称空间====>局部名称空间

名字的查找顺序:

局部名称空间=====>全局名称空间====>内置模块的名称空间

Python中名称空间与作用域 的关系:

作用域:全局作用域和局部作用域

其中全局作用域包括内置名称空间与全局名称空间定义的名字;局部作用域包括在局部名称空间定义的名字。

注意:默认情况下在局部作用域内不能修改全局作用域范围内的变量,只能调用数值,如果想修改,只能通过global关键字进行修改。

示例程序1:

代码语言:javascript
复制
def outer():
    a = 0
    b = 1

    def inner():
        print(a)
        print(b)

    inner()
    return 20

outer()

示例程序2:

代码语言:javascript
复制
def outer():
    a = 0
    b = 1

    def inner():
        print(a)
        print(b)

        b = 4

    inner()

outer()

错误信息:变量b在赋值前被引用。

代码语言:javascript
复制
0
Traceback (most recent call last):
  File "D:/Python Work Location/Core2/Test3.py", line 16, in <module>
    outer()
  File "D:/Python Work Location/Core2/Test3.py", line 14, in outer
    inner()
  File "D:/Python Work Location/Core2/Test3.py", line 10, in inner
    print(b)
UnboundLocalError: local variable 'b' referenced before assignment

请继续关注我

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档