社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python对变量的重新声明在内部是如何工作的?

il velan • 3 年前 • 1110 次点击  

我对Python相当陌生,所以对一些人来说,这似乎是一个微不足道的问题。但我很好奇,当您将一个新对象绑定到一个变量时,Python内部是如何工作的,它指的是绑定到同一变量名的前一个对象。请以下面的代码为例——我知道python打破了与原始对象“hello”的联系,将其绑定到新对象,但这里的事件顺序是什么?python如何打破与原始对象的联系,同时又引用它?

greeting = 'hello'
greeting = f'y{greeting[1:len(greeting)]}' 

除了解释,我也非常感谢一些上下文。我知道字符串是不可变的,但其他类型如浮点数和整数呢? 我是否理解python内部的运行方式重要吗?此外,如果Python能够在内部工作,那么哪里是了解Python如何工作的好地方呢?

希望我的问题清楚。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/133356
 
1110 次点击  
文章 [ 2 ]  |  最新文章 3 年前
Tim Roberts
Reply   •   1 楼
Tim Roberts    3 年前

在第二行中,Python对赋值语句的右侧求值,这将创建一个使用旧绑定的字符串 greeting .只有在对该表达式求值之后,它才会处理赋值运算符,该运算符将该字符串绑定到名称。这都是线性的。

浮点数和整数也是不可变的。只有列表和字典是可变的。实际上,目前还不清楚在任何情况下如何修改integer对象。你指不到物体的内部。重要的是要记住,在这种情况下:

i = 3
j = 4
i = i + j

最后一行只是创建一个新的整数/浮点对象并将其绑定到 i 。所有这些都不会试图修改integer对象 3 .

我写了这篇文章,试图描述Python对象和我们使用的名称之间的区别:

https://github.com/timrprobocom/documents/blob/main/UnderstandingPythonObjects.md

ShadowRanger
Reply   •   2 楼
ShadowRanger    3 年前

通过分解的媒介进行解释:

>>> dis.dis('''greeting = 'hello'
... greeting = f'y{greeting[1:len(greeting)]}'
... ''')
  1           0 LOAD_CONST               0 ('hello')
              2 STORE_NAME               0 (greeting)

  2           4 LOAD_CONST               1 ('y')
              6 LOAD_NAME                0 (greeting)
              8 LOAD_CONST               2 (1)
             10 LOAD_NAME                1 (len)
             12 LOAD_NAME                0 (greeting)
             14 CALL_FUNCTION            1
             16 BUILD_SLICE              2
             18 BINARY_SUBSCR
             20 FORMAT_VALUE             0
             22 BUILD_STRING             2
             24 STORE_NAME               0 (greeting)
             26 LOAD_CONST               3 (None)
             28 RETURN_VALUE

最左边的数字表示特定行字节码的起始位置。第1行非常简单,所以我将解释第2行。

正如您可能注意到的,您的f字符串在编译后无法保存;它变成了一堆原始操作码,将常量段的加载与格式占位符的计算混合在一起,最终导致堆栈顶部出现构成最终字符串的所有片段。当它们都在堆栈上时,它会将所有的片段放在一起,最后用 BUILD_STRING 2 (上面写着“从堆栈中取出最上面的两个值,并将它们组合成一个字符串”)。

greeting 只是一个有约束力的名字。它实际上并不包含一个值,只是对它当前绑定到的任何对象的引用。原始引用被推到堆栈上(使用 LOAD_NAME )完全是在 STORE_NAME 这会弹出堆栈顶部并重新绑定 招呼 .

简而言之,它之所以有效,是因为 招呼 被替换时不再需要;它被用来生成新字符串,然后被丢弃,取而代之的是新字符串。