python输出变量地址_Python——变量

2023-05-16

笑虎:千行代码入门Python​zhuanlan.zhihu.com

函数的参数​www.liaoxuefeng.com

Python学习之变量的作用域 - fireporsche - 博客园​www.cnblogs.com

1.Python数据类型:

Python数据类型有两种:哈希类型、不可哈希类型,这是因为hash函数的结果和变量的地址有关。

哈希类型,即在原地不能改变的变量类型,不可变类型。可利用hash函数查看其hash值,也可以作为字典的key。

"数字类型:int, float, decimal.Decimal, fractions.Fraction, complex"

"字符串类型:str, bytes"

"元组:tuple"

"冻结集合:frozenset"

"布尔类型:True, False"

"None"

不可hash类型:原地可变类型:list、dict和set。它们不可以作为字典的key。

2.在python中赋值符号=

在python中 a=b=0,其实a是对b的引用,即a,b指向同一块内存空间:可以看到a和b的地址一样,这里可能看不出来a,b与c的区别

>>> a=b=0

>>> id(a)

140726709150320

>>> id(b)

140726709150320

>>> c=0

>>> id(c)

140726709150320

对于不可哈希数值可以看到c与a,b的id不一样

>>> a=b=[]

>>> c=[]

>>> id(a)

2454206440072

>>> id(b)

2454206440072

>>> id(c)

2454206440136

更改a的值,对于常量,a的指向改变,而对于不可hash类型,指向不变:

>>> a=b=0

>>> a=1

>>> a=b=0

>>> id(a)

140726709150320

>>> id(b)

140726709150320

>>> a=1

>>> id(a)

140726709150352

>>> id(b)

140726709150320

>>> a

1

>>> b

>>> a=b=[]

>>> c=[]

>>> id(a)

2454206440072

>>> id(b)

2454206440072

>>> id(c)

2454206440136

>>> a.append(1)

>>> a

[1]

>>> b

[1]

>>> c

[]

>>>

3.不可hash类型在作为函数的默认参数时带来的问题

例如:

def f(x,li=[]):

for i in range(x):

li.append(i*i)

print(li)

print('---1---')

f(4)

print('---2---')

f(5)

预期结果

---1--- [0, 1, 4, 9]

---2--- [0, 1, 4, 9, 16]

执行结果

---1---

[0, 1, 4, 9]

---2---

[0, 1, 4, 9, 0, 1, 4, 9, 16]

这是因为当定义函数时,会保存函数中默认参数 list 的值,也就是列表 li=[];(也是就函数中默认参数的定义是在函数定义时就分配好空间了)

在每次调用的时候如果传递了新的列表,则使用传递的列表,没有传递,使用定义函数时保存的默认参数(li=[]);

上面两次调用中,都没有传递新的列表(使用默认列表 li=[] ),程序会调用定义函数时保存的默认参数((li=[]));

解决办法1:

在函数中增加判断li是否为[],不为空时,赋值为空

def f(x, li=[]):

if not li:

# 如果li不为空的话,就往下走(清空列表); 为空就不走

li = []

for i in range(x):

li.append(i * i)

print(li)

print('---1---')

f(4)

print('---2---')

f(5)

print('---3---')

f(6)

结果:

---1---

[0, 1, 4, 9]

---2---

[0, 1, 4, 9, 16]

---3---

[0, 1, 4, 9, 16, 25]

解决办法2:

def add_end(L=None):

if L is None:

L = []

L.append('END')

return L

4.变量作用域

4.1变量的作用域

在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域。python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量能被访问的范围。即Python变量的作用域由变量所在源代码中的位置决定。

4.2高级语言对数据类型的使用过程

一般的高级语言在使用变量时,都会有下面4个过程。当然在不同的语言中也会有着区别。

声明变量:让编辑器知道有这一个变量的存在

定义变量:为不同数据类型的变量分配内存空间

初始化:赋值,填充分配好的内存空间

引用:通过引用对象(变量名)来调用内存对象(内存数据)

4.3 python中的作用域

就作用域而言,Python与C有着很大的区别,在Python中并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。也就是说只有Module(模块)、Class(类)、def(函数)才是作用域划分的标值。

看下面的代码:

#!/usr/bin/env python

def func():

variable = 100

print variable

print variable

代码的输出为:

NameError: name 'variable' is not defined

而在if-elif-else、for-else、while、try-except\try-finally等关键字的语句块中并不会产成作用域。看下面的代码:

if True:

variable = 100

print (variable)

print ("******")

print (variable)

代码的输出为:

100

******

100

所以,可以看到,虽然是在if语句中定义的variable变量,但是在if语句外部仍然能够使用。

4.4作用域的类型:

在Python中,使用一个变量时并不严格要求需要预先声明它,但是在真正使用它之前,它必须被绑定到某个内存对象(被定义、赋值);这种变量名的绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量。

L(local)局部作用域

局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。有些情况需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。局部变量域就像一个 栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。

注意:如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。

E(enclosing)嵌套作用域

E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。与L的区别在于,对一个函数而言,L是定义在此函数内部的局部作用域,而E是定义在此函数的上一层父级函数的局部作用域。主要是为了实现Python的闭包,而增加的实现。

G(global)全局作用域

即在模块层次中定义的变量,每一个模块都是一个全局作用域。也就是说,在模块文件顶层声明的变量具有全局作用域,从外部开来,模块的全局变量就是一个模块对象的属性。

注意:全局作用域的作用范围仅限于单个模块文件内

B(built-in)内置作用域

系统内固定模块里定义的变量,如预定义在builtin 模块内的变量。

4.5变量名解析LEGB法则

搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域

LEGB法则: 当在函数中使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,以此来确定该变量名的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,则会出发NameError错误。

几个实例:

1.

def func():

variable = 300

print variable

variable = 100

func() #300

print variable #100

2.

variable = 300

def test_scopt():

print variable #variable是test_scopt()的局部变量,但是在打印时并没有绑定内存对象。

variable = 200 #因为这里,所以variable就变为了局部变量

test_scopt()

print variable

上面的例子会报出错误,因为在执行程序时的预编译能够在test_scopt()中找到局部变量variable(因为 test_scopt()中有variable的赋值表达式,在预编译阶段就找到了该变量,即变量已经声明过,但是还未开辟空间和赋值)。在局部作用域找到了变量名,所以不会升级到嵌套作用域去寻找。但是在使用print语句将变量variable打印时,局部变量variable并有没绑定到一个内存对象(没有定义和初始化,也没有赋值)。本质上还是Python调用变量时遵循的LEGB法则和Python解析器的编译原理,决定了这个错误的发生。所以,在调用一个变量之前,需要为该变量赋值(绑定一个内存对象)。

注意:为什么在这个例子中触发的错误是UnboundLocalError而不是NameError:name ‘variable’ is not defined。因为变量variable不在全局作用域。所以在test_scopt()这个局部作用域中找到了variable但是却没有被绑定内存空间(分配内存和初始化赋值),自燃也就不能使用(引用)

Python中的模块代码在执行之前,并不会经过预编译,但是模块内的函数体代码在运行前会经过预编译,因此不管变量名的绑定发生在作用域的那个位置,都能被编译器知道。Python虽然是一个静态作用域语言,但变量名查找是动态发生的,直到在程序运行时,才会发现作用域方面的问题

4.6 nonlocal和global语句的区别

nonlocal和global语句的功能不同。global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。

如果想在局部空间使用全局变量或是该局部作用域以外的变量怎么办呢?使用全局变量,可以用global关键字来声明该变量是来自全局变量

2. 使用上一级函数中的局部变量则可以用nonlocal关键字

3.按照LEGB法则,依次寻找变量

# nonlocal应用于一个嵌套的函数的作用域中的一个名称 例如:

start = 100

def tester(start):

def nested(label):

nonlocal start # 指定start为tester函数内的local变量 而不是global变量start

print(label, start)

start += 3

return nested

start=0

# global为全局的变量 即def之外的变量

def tester(start):

def nested(label):

global start # 指定start为global变量start

print(label, start)

start += 3

return nested

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python输出变量地址_Python——变量 的相关文章

  • 如何把父母和孩子联系起来?

    有两个简单的类 一个只有parent属性 并且两者兼而有之parent and children属性 这意味着同时具备两者的人parent and children继承自唯一的parent 这是只有parent属性 我们就这样称呼它吧Chi
  • Vimeo API:获取下载所有视频文件的链接列表

    再会 我正在尝试从 Vimeo 帐户获取所有视频文件的列表 直接下载的链接 有没有办法在 1 GET 请求中做到这一点 好的 如果是API限制的话 就100倍 我有硬编码脚本 我在其中发出 12 个 GET 请求 1100 多个视频 根据文
  • 为什么 Mypy 在 __init__ 中分配已在类主体中进行类型提示的属性时不给出键入错误?

    这是我的示例 python 文件 class Person name str age int def init self name age self name name self age age p Person 5 5 但当我跑步时myp
  • 如何让“conda”安装程序查找“PyPi”包

    我试图使用conda http conda pydata org docs using pkgs html managing packages包管理器来安装我的 Python 包 最近 我遇到了 Anaconda org 存储库中不存在我需
  • 导入错误:无法导入名称“FFProbe”

    我无法获取ffprobe包 https github com simonh10 ffprobe在 Python 3 6 中工作 我使用 pip 安装它 但是当我输入import ffprobe it says Traceback most
  • docker 容器中的“(pygame parachute)分段错误”

    尝试在 docker 容器中使用 pygame 时出现以下错误 我想从容器中获取显示 Fatal Python error pygame parachute Segmentation Fault 重现 Docker已安装 docker ru
  • DynamodB:如何更新排序键?

    该表有两个键 filename 分区键 和eventTime 排序键 我要更新eventTime对于某些filename Tried put item and update item 发送相同的filename与新的eventTime但这些
  • Scrapy 文件管道不下载文件

    我的任务是构建一个可以下载所有内容的网络爬虫 pdfs 在给定站点中 Spider 在本地计算机和抓取集线器上运行 由于某种原因 当我运行它时 它只下载一些但不是全部的 pdf 通过查看输出中的项目可以看出这一点JSON 我已经设定MEDI
  • 使用 Pandas 从 csv 文件读取标题信息

    我有一个包含 14 行标题的数据文件 在标头中 有经纬度坐标和时间的元数据 我目前正在使用 pandas read csv filename delimiter header 14 读取文件 但这只是获取数据 我似乎无法获取元数据 有人知道
  • 为什么需要设置WORKON_HOME环境变量?

    我已经有一段时间没有使用 python 虚拟环境了 但我也安装了虚拟环境包装器 我的问题是 在文档页面中它说要这样做 export WORKON HOME Envs mkdir p WORKON HOME source usr local
  • 如何从 python 脚本执行 7zip 命令

    我试图了解如何使用 os system 模块来执行 7zip 命令 现在我不想用 Popen 或 subprocess 让事情变得复杂 我已经安装了 7zip 并将 7zip exe 复制到我的用户文件夹中 我只想提取我的测试文件 inst
  • Pandas 字典键到列[重复]

    这个问题在这里已经有答案了 我有一个像这样的数据框 index column1 e1 u c680 5 u c681 1 u c682 2 u c57 e2 u c680 6 u c681 2 u c682 1 u c57 e3 u c68
  • 使用 python 脚本更改 shell 中的工作目录

    我想实现一个用户态命令 它将采用其参数之一 路径 并将目录更改为该目录 程序完成后 我希望 shell 位于该目录中 所以我想实施cd命令 但需要外部程序 可以在 python 脚本中完成还是我必须编写 bash 包装器 Example t
  • 在 django 中导入设置时出现奇怪的错误

    我有很多项目在 ubuntu 中使用 python2 7 和 virtualenv virtualenvwrapper 工作 在我的工作中 一些开发人员使用 macosx 和 windows 通常我像往常一样创建项目 django admi
  • Python在没有pandas的情况下解码excel表

    我正在尝试在 python 中读取 excel 文件而不使用pandas or xlrd 我一直在尝试将结果转换为bytes to utf 8没有任何成功 xls 文件中的数据 colA colB colC spc 1D0 20190705
  • Python:导入模块一次然后与多个文件共享

    我有如下文件 file1 py file2 py file3 py 假设这三个都使用 lib7 py lib8 py lib9 py 目前 这三个文件中的每一个都有以下行 import lib7 import lib8 import lib
  • 将 Django 中的所有视图限制为经过身份验证的用户

    我是 Django 新手 我正在开发一个项目 该项目有一个登录页面作为其索引和一个注册页面 其余页面都必须仅限于登录用户 如果未经身份验证的用户尝试访问这些页面 则必须将他 她重定向到登录页面 我看到 login required装饰器会将
  • 类返回语句不打印任何输出

    我正在学习课程 但遇到了问题return语句 它是语句吗 我希望如此 程序什么也没有打印出来 它只是结束而不做任何事情 class className def createName self name self name name def
  • SQLAlchemy 与 count、group_by 和 order_by 使用 ORM

    我有几个函数需要使用 count group by 和 order by 进行一对多连接 我使用 sqlalchemy select 函数生成一个查询 该查询将返回一组 id 然后我对其进行迭代以对各个记录执行 ORM 选择 我想知道是否有
  • 超过两个点的Python相对导入

    是否可以使用路径中包含两个以上点的模块引用 就像这个例子一样 Project structure sound init py codecs init py echo init py nix init py way1 py way2 py w

随机推荐