python入口函数的作用_python之函数中参数的作用域

学编程究竟学的是什么呢?在写文章的这几天也一直在思考这个问题——恐怕这也是接下来的几年一直会去思考的问题。这个问题的答案也会指导我的方法论,所以索性整顿一下。

现阶段我的回答是,发现需求,然后解决。

最大的需求无非是完成一个项目,为了做到这一点,还有很多需求是完成模块化的功能,再细分下去则是要实现每一个具体的函数。这些都做到了,可能整个功能就跑通了。但是,需求其实没有止步:代码效率能更高么?

鲁棒性能优化么?

可读性能改善么?

整体功能的架构完善么?

甚至工程细节,debug效率能更高么?

logger输出能更合理么?

这些需求则是关系到积累,可不只是一次项目就能简单回答的,需要更深的思考和总结。

所以,在学习中怎么贯彻这一点呢?将学到的知识和项目尽量建立联系,以后的知识点的例子我也会尽量从这方面去构建。

查看python源码。很多需求提不出来的原因是见得不够多,但是源码里,很多经验丰富的前辈不仅预见了这些需求,还封装了这个需求的解决办法。所以不仅对现阶段有帮助,也能是下一阶段——如何把问题解决的更高效的预热。

下面,我们开始讨论面向过程抽象的最基本也是最重要的单位——函数。

环境与作用域

在SICP(第三章)中对环境有着如下定义:一个环境是框架(frame)的一个序列,每个框架是包含着一些约束的一个表格(可能为空),这些约束将一些变量的名字关联于对应的值(在一个框架里,任何变量至多只能有一个约束)。每一个框架还包含了一个指针,指向这一框架的外部环境......

当时走马观花的看到了这个定义,但是在python中debug的时候才发现理解了环境是多么的好用:我们可以通过选取不同的frame,观看到不同的变量在各个环境中是如何变化的。

但是被动的使用肯定是不足够的,我们还是要主动的洞察变量定义和frame的关系,更好的预见我们写出的代码真实的效果是什么。(SICP大法好。。自学者还是要夯实基础。虽然第一次看的时候似懂非懂,不过这就是积累哦,第二次看到的时候就有机会融会贯通了)

变量名解析原则LEGB

其实上述一大段话,说的是这个意思:如果当前frame里有这个变量,直接引用,否则去上层frame中查找是否有同名变量,直到找到最高层;若都没有就报错咯~

看个例子

x = 1

def fun():

print(x)

fun()

# 1

引用好说,但当牵扯到赋值的时候,就不那么显然了

x = 1

def fun():

x = 1

print(x)

fun()

# 2

这个还好,比较符合大家直观感受,但是下面就不一样了

x = 1

def fun():

x += 1

print(x)

fun()

# UnboundLocalError: local variable 'x' referenced before assignment

既然引用没错,这咋不能引用加赋值呢??原来,在函数内部,一旦牵扯到赋值语句,变量就会变成局部变量,像第二个例子一样屏蔽掉全局变量x(x=1)。如果想改变全局变量,那么就在函数内部事先声明

def fun():

global x

...

这样,我们就有一个比较直观的感觉:牵扯到在函数内部赋值时,如果是内部变量没什么关系,但如果改变外部变量的话,一定要像一个办法将其引入内部空间(一般不是global);相反,如果仅仅是普通引用的话则十分方便,无需过度担心。

但是如果函数嵌套的话会发生什么情况呢?显见,最内层函数的外一层就不再是global环境。具体的层次就是所谓的LEGB。Scope Resolution in Python | LEGB Rule - GeeksforGeeks​www.geeksforgeeks.orgv2-1de4edc1cecbd4280e1eb3f437333e16_ipico.jpg

文中小图清晰的展现了frame的嵌套关系。留一个问题:如果import了其他py文件,frame结构又是什么样子的呢?

frame的存在时间

最后举一个特别精巧的例子,在这个例子中,我们把函数作为另一个函数的返回值。熟悉数学的朋友们知道这个在数学里叫做泛函,是一种强有力的抽象手段。如果有机会会在SICP中好好讨论一下这种所谓的过程的抽象。

def counter():

c = [0]

def inc():

c[0] += 1

return c[0]

return inc

f = counter()

f()

# 1

f()

# 2

f()

# 3

从这个例子不难看出,局部变量c一直存在在f所代表的frame当中。如果g=counter(),则g的计数与f毫无关联。

为什么可以c[0] += 1?这是因为,我们赋值的是变量c所代表的列表中的元素,即,本质上,我们对c是引用,所以在local frame中找不到c时,我们能从enclosed frame中找到c拿来引用。

(这个例子给了我们做计数器的巨大的启发。

默认值的本质

def fun(x=[1]):

x.append([2])

print(x)

# 比较下面两个输出

for _ in range(2):

fun()

# [1, 2]

# [1, 2, 2]

for _ in range(2):

fun([1])

# [1, 2]

# [1, 2]

原来,函数中有这两个属性收集默认值:fun.__defaults__ 收集默认位置参数

fun.__kwdefaults_ 收集默认关键字参数

如果我们不明确的赋值,则调用默认值。但是!!因为我们这里的默认值可变(虽然列表的内存地址没有改变,但是列表的内容变了),所以我们的行为也许会修改默认值!

只要函数不被销毁,作为属性的默认值就会一直记录所有的改变。

首先,我们要意识到,这种做法有时有利,有时有害,不可一概而论;下面我们展示两种方法:如果一旦我们不想让默认值改变,该采取什么做法。

def fun(x=[]):

x = x[:] # shadow copy

....

第一方面,如果传入了x,立即对xshadow copy,没问题;如果没传入,我们操作的是默认值x的shadow copy,而不是x本身,所以。。。?

这里比较讨巧,用了一个空列表,如果一个默认值很复杂(其实不推荐复杂的默认值吧。。),那么shadow copy也是会有shadow copy的问题的对吧?

所以这种做法须谨慎。

def fun(x=None):

if x is None:

x = []

....

哇!这个方法还是厉害的咧。也是推荐大家使用的。每次调用,对x重新赋值,肯定能避免这次的改变泄漏到下次操作中。

我们也可以这么理解:

函数的属性,和函数定义本身绑定在一起,存在于global frame(假设是最外层函数);而每次调用函数,就会自动生成一个新的local frame。所以,方法二中的赋值方法是没有问题的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea lombok 离线安装_Lombok与IntelliJ IDEA干了一架,完胜

我相信前段时间,有更新IDEA到2020.2版本的同学,在安装Lombok的过程中,肯定遇到与Lombok无法兼容的问题,并且报错:Caused by: com.intellij.psi.PsiInvalidElementAccessException: Element: class de.plushnikov.intel…

jquery设置宽_JavaScript学习笔记(三十二) jQuery(中)

jQuery昨天讲了 jQuery 的基本选择器筛选器和属性操作今天来说一些 jQuery 别的东西元素操作创建一个元素var div $()内部插入元素// 向 div 元素中插入一个 p 元素,放在最后$(div).append($())// 把 p 元素插入到 div 中去,放在最后$(hello).appendTo(…

python自动化框架测试实操_自动化框架之 python+selenium+pytest

1.概述 selenium: 基于JavaScript代码库的自动化测试框架,通过脚本语言,模拟用户行为操作,最接近用户真实场景,实现对web自动测试。 Selenium,是目前的最火爆企业最主流的webUI自动化框架 pytest: pytest是…

mysql 关联查询慢_mysql慢查询语句分析总结

我们经常会接触到MySQL,也经常会遇到一些MySQL的性能问题。我们可以借助慢查询日志和explain命令初步分析出SQL语句存在的性能问题通过SHOW FULL PROCESSLIST查看问题SHOW FULL PROCESSLIST相当于select * from information_schema.processlist可以列出正在运行的连…

python opencv3 轮廓检测

git:https://github.com/linyi0604/Computer-Vision 1 # coding:utf82 3 import cv24 import numpy as np5 6 # 创建一个200*200 的黑色空白图像7 img np.zeros((200, 200), dtypenp.uint8)8 # 在图像的中央位置 放置一个100*100的白色方块9 img[50:150, 50: 150] …

CentOS7搭建NTP服务器

搭建ntp服务器 查看服务器、客户端操作系统版本 2查看服务器是否安装ntp 3如果没有安装 4安装完成后重新查看服务器是否安装ntp 5查看ntp服务器状态 6修改配置文件 注释 #server 0.centos.pool.ntp.org iburst #server 1.centos.pool.ntp.org iburst #server 2.centos.p…

mysql 5.7.21-linux_MySQL 5.7.21 Linux平台安装 Part 2

从今天开始MySQL相关方面的东西今天是关于MySQL的安装系统为 redhat 6.10数据库为MySQL 5.7.21PS:目前最新版本为MySQL 5.7.251. 目录规划2. MySQL 5.7 下载目前MySQL 社区的GA 提供5 和8 的下载由于目前大多数系统用的还是5的版本这里统一使用5的版本注意,下面是按…

session很快失效_深夜,我偷听到程序员要对session下手...

我是一个web服务器我的工作是给人类提供上网服务,我每天要为数以万计的人提供网页浏览服务。已经是深夜了,我还在和手下几个兄弟为了一件事紧张讨论着。“老大,现在咱们每天处理的请求越来越多了,session同步的问题不能再拖了&…

centos7安装samba服务器

1查看是否安装samba服务 2如果为空则没有安装,安装显示安装完成即成功 3查看samba状态 4查看配置文件的位置 5配置文件备份,直接传输到本地备份 6修改配置文件 Path共享目录位置 Valid users 可以查看的用户 Browseable可以查看共享文件夹的目录&a…

微信小程序—day01

前言 听说谷歌准备回中国了,玩了一下谷歌刚入驻微信的小程序:“猜画小歌”,又一次见识到了ai的强大魅力。看来python之路,前途还是一片光明的。 因为18年初时的“跳一跳”,带火了微信小程序,一直想要写一个…

docker mysql 操作_[Docker] Docker 快速搭建本地MySQL开发环境

[Docker] Docker 快速搭建本地MySQL开发环境关于 Docker 的安装使用本文不再赘述,有兴趣的可以通过官网或是浏览我的专栏文章了解。今天着重给大家介绍下如何利用Docker快速搭建一个MySQL的环境,来协助本地开发。TOC手机用户请横屏获取最佳阅读体验&…

centos7安装DHCP服务器

1检查防火墙和selinux(关闭) 关闭防火墙和selinux,这边不多说 2检查DHCP状态 3安装DHCP软件包 4把系统默认的样例复制 5修改配置文件 option domain-name “example.org”; --DNS域名 option domain-name-servers ns1.example.org, ns2.…

python装饰器解析_Python 装饰器解析

一、装饰器定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能 二、装饰器的作用:在不改变原函数的情况下,为原函数前后添加新的功能 三、装饰器的原则: 1、不能修改被装饰的函数的源代…

centos7网卡识别不到,无法远程工具连接

这是在安装dhcp的时候遇到的问题,远程工具连接不上了。没IP地址没得玩 解决办法 直接在虚拟机打开终端,找到配置文件ifcfg-ens33 TYPE“Ethernet” PROXY_METHOD“none” BROWSER_ONLY“static”----原先的dhcp换成static BOOTPROTO“no” DEFROUTE“ye…

python爬虫脚本ie=utf-8_Python反爬虫伪装浏览器进行爬虫

对于爬虫中部分网站设置了请求次数过多后会封杀ip,现在模拟浏览器进行爬虫,也就是说让服务器认识到访问他的是真正的浏览器而不是机器操作 简单的直接添加请求头,将浏览器的信息在请求数据时传入: 打开浏览器--打开开发者模式--请…

centos7加入第二块网卡无法识别

本来是做DHCP服务加一块网卡的,然后识别不出来,没得玩 centos7加入第二块网卡无法识别 1发现只有一块网卡 2使用nmcli con show命令,查看网卡的UUID信息,记下UUID值 3启动networkManager’ 4识别 5使用ip addr命令查看网卡信息…

hbase 导入mysql_HBase导入SQL Server数据库数据

在先前的几篇随笔中已经介绍了Hadoop、Zookeeper、Hbase的分布式框架搭建方案,目前已经搭建完成了一个包含11个节点的分布式集群。而对于HBase数据库的使用仅限于测试性质的增删改查指令,为了进一步熟悉分布式框架的使用,本文介绍将已有的数据…

googlenet网络结构_CNN网络结构的发展

 CNN基本部件介绍,1. 局部感受野在图像中局部像素之间的联系较为紧密,而距离较远的像素联系相对较弱。因此,其实每个神经元没必要对图像全局进行感知,只需要感知局部信息,然后在更高层局部信息综合起来即可得到全局信…

linux数据库mysql的安装

1数据库文件放到opt下面 2赋予权限775 3运行脚本 4运行成功 5数据库操作 密码修改并刷新 权限修改,允许外部设备访问 6工具连接 7附录 1、显示当前数据库服务器中的数据库列表:   mysql> SHOW DATABASES;   2、建立数据库:   …

智能优化算法应用:基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.侏儒猫鼬算法4.实验参数设定5.算法结果6.…