Python与C中每行的多个属性
尽我所能理解python的工作原理。我有着坚实的C语言背景 正在尝试将以下行转换为C:Python与C中每行的多个属性,python,c,translation,Python,C,Translation,尽我所能理解python的工作原理。我有着坚实的C语言背景 正在尝试将以下行转换为C: p,q=q,p-x//y*q 我的问题是,多个断言/属性(请纠正我的术语)不能像我期望的那样工作 这行代码实际上是如何展开为类似C的语法的?在C中,您可以使用以下方法执行相同的操作: temp=p-x/y*q; p=q; q=温度; 但实际情况是,右侧创建了一个元组,元组项从左到右构建: t=(q,p-x//y*q) 然后,元组在左侧被解包: p = t[0] q = t[1] 使用元组进行本质上的并行
p,q=q,p-x//y*q
我的问题是,多个断言/属性(请纠正我的术语)不能像我期望的那样工作
这行代码实际上是如何展开为类似C的语法的?在C中,您可以使用以下方法执行相同的操作:
temp=p-x/y*q;
p=q;
q=温度;
但实际情况是,右侧创建了一个元组,元组项从左到右构建:
t=(q,p-x//y*q)
然后,元组在左侧被解包:
p = t[0]
q = t[1]
使用元组进行本质上的并行赋值非常方便。我相信你很快就会习惯的
但有一件事可能需要更长的时间才能习惯,那就是Python的数据模型,它的工作方式与C完全不同。您可能会发现这篇文章很有帮助:,它是由经验丰富的Ned Batchelder撰写的。您可以用C语言做与之类似的事情:
temp=p-x/y*q;
p=q;
q=温度;
但实际情况是,右侧创建了一个元组,元组项从左到右构建:
t=(q,p-x//y*q)
然后,元组在左侧被解包:
p = t[0]
q = t[1]
使用元组进行本质上的并行赋值非常方便。我相信你很快就会习惯的
但有一件事可能需要更长的时间才能习惯,那就是Python的数据模型,它的工作方式与C完全不同。您可能会发现这篇文章很有帮助:,它是由经验丰富的Ned Batchelder撰写的。任何作品都需要首先计算右侧的表达式,然后将其分配给目标列表。1
在您的案例中,右侧是一个包含两个元素的图形:
q, p - x // y * q
因此,Python计算第一个元素q
,然后计算第二个元素p-x//y*q
,然后用这两个值构建一个元组
接下来,由于您有一个左侧有两个目标的目标列表,Python使用iterable unpacking(在同一个元组和序列教程部分中描述)2将该元组解压为两个单独的值,并为每个目标分配一个值
所以,用C表示,它大致是:
_tmp1 = q
_tmp2 = p - x // y * q
_tmp3 = (_tmp1, _tmp2)
p = _tmp3[0]
q = _tmp3[1]
事实上,一个真正的Python实现可能会优化build-a-tuple/unpack-a-tuple代码,这与您自己编写此代码的方式相同,因此您得到的结果更像:
_tmp = p - x // y * q
p = q
q = _tmp
如果您习惯于C语言,您可能会习惯于查看编译器生成的程序集(没有禁用优化),以了解某些东西的真正含义。在Python中,除了汇编语言用于CPython字节码,而不是用于x86_64或ARM9或其他任何东西之外,您可以对模块执行相同的操作:
>>> import dis
>>> dis.dis('p, q = q, p - x // y * q')
1 0 LOAD_NAME 0 (q)
2 LOAD_NAME 1 (p)
4 LOAD_NAME 2 (x)
6 LOAD_NAME 3 (y)
8 BINARY_FLOOR_DIVIDE
10 LOAD_NAME 0 (q)
12 BINARY_MULTIPLY
14 BINARY_SUBTRACT
16 ROT_TWO
18 STORE_NAME 1 (p)
20 STORE_NAME 0 (q)
22 LOAD_CONST 0 (None)
24 RETURN_VALUE
如您所见,在CPython 3.7中,它实际上优化了元组,也优化了临时局部变量,只是在堆栈上匿名存储了中间值
一,。这有点过于简单,因为像
spam[eggs][0]=…
这样的目标实际上需要将spam[eggs]
作为一个表达式进行评估,然后将[0]
作为一个目标……但这与此无关
二,。本教程称之为“序列解包”,因为它还没有达到“iterable”的概念。任何方法都是先计算右侧的表达式,然后将其分配给目标列表。1
在您的案例中,右侧是一个包含两个元素的图形:
q, p - x // y * q
因此,Python计算第一个元素q
,然后计算第二个元素p-x//y*q
,然后用这两个值构建一个元组
接下来,由于您有一个左侧有两个目标的目标列表,Python使用iterable unpacking(在同一个元组和序列教程部分中描述)2将该元组解压为两个单独的值,并为每个目标分配一个值
所以,用C表示,它大致是:
_tmp1 = q
_tmp2 = p - x // y * q
_tmp3 = (_tmp1, _tmp2)
p = _tmp3[0]
q = _tmp3[1]
事实上,一个真正的Python实现可能会优化build-a-tuple/unpack-a-tuple代码,这与您自己编写此代码的方式相同,因此您得到的结果更像:
_tmp = p - x // y * q
p = q
q = _tmp
如果您习惯于C语言,您可能会习惯于查看编译器生成的程序集(没有禁用优化),以了解某些东西的真正含义。在Python中,除了汇编语言用于CPython字节码,而不是用于x86_64或ARM9或其他任何东西之外,您可以对模块执行相同的操作:
>>> import dis
>>> dis.dis('p, q = q, p - x // y * q')
1 0 LOAD_NAME 0 (q)
2 LOAD_NAME 1 (p)
4 LOAD_NAME 2 (x)
6 LOAD_NAME 3 (y)
8 BINARY_FLOOR_DIVIDE
10 LOAD_NAME 0 (q)
12 BINARY_MULTIPLY
14 BINARY_SUBTRACT
16 ROT_TWO
18 STORE_NAME 1 (p)
20 STORE_NAME 0 (q)
22 LOAD_CONST 0 (None)
24 RETURN_VALUE
如您所见,在CPython 3.7中,它实际上优化了元组,也优化了临时局部变量,只是在堆栈上匿名存储了中间值
一,。这有点过于简单,因为像
spam[eggs][0]=…
这样的目标实际上需要将spam[eggs]
作为一个表达式进行评估,然后将[0]
作为一个目标……但这与此无关
二,。本教程称之为“序列解包”,因为它还没有达到“iterable”的概念