标签: python-internals

什么时候.pyc文件刷新?

我知道".pyc"文件是纯文本".py"文件的编译版本,在运行时创建以使程序运行得更快.但是我发现了一些事情:

  1. 修改"py"文件后,程序行为会发生变化.这表示"py"文件已编译或至少通过某种散列过程或比较时间戳来判断是否应重新编译它们.
  2. 删除所有".pyc"文件(rm *.pyc)后,程序行为有时会发生变化.这表明他们没有在".py"更新时编译.

问题:

  • 他们如何决定何时编译?
  • 有没有办法确保他们在开发过程中进行更严格的检查?

python pyc python-internals

84
推荐指数
2
解决办法
5万
查看次数

在Python中覆盖对象的复制/深度复制操作的正确方法是什么?

所以只是为了建立,我觉得我理解复制模块中的copyvs 之间的区别deepcopy,我已经使用过copy.copy并且copy.deepcopy成功之前,但这是我第一次真正去重载__copy____deepcopy__方法.我已经围绕谷歌搜索,并通过看内置的Python模块查找的实例__copy____deepcopy__功能(例如sets.py,decimal.pyfractions.py),但我仍然肯定不是100%我已经得到了它的权利.

这是我的情景:

我有一个配置对象,它主要由简单属性组成(尽管它可能包含其他非基本对象的列表).最初,我将使用一组默认值来实例化一个配置对象.此配置将切换到多个其他对象(以确保所有对象以相同的配置启动).然而,一旦用户交互开始,每个对象将需要能够独立地调整配置而不影响彼此的配置(对我来说,我需要使用我的初始配置的深度复制来处理).

这是一个示例对象:

class ChartConfig(object):

    def __init__(self):

        #Drawing properties (Booleans/strings)
        self.antialiased = None
        self.plot_style = None
        self.plot_title = None
        self.autoscale = None

        #X axis properties (strings/ints)
        self.xaxis_title = None
        self.xaxis_tick_rotation = None
        self.xaxis_tick_align = None

        #Y axis properties (strings/ints)
        self.yaxis_title = None
        self.yaxis_tick_rotation = None
        self.yaxis_tick_align = None

        #A list of non-primitive objects
        self.trace_configs = [] …
Run Code Online (Sandbox Code Playgroud)

python python-internals

82
推荐指数
5
解决办法
5万
查看次数

Python:为什么*和**比/和sqrt()更快?

在优化我的代码时,我意识到以下内容:

>>> from timeit import Timer as T
>>> T(lambda : 1234567890 / 4.0).repeat()
[0.22256922721862793, 0.20560789108276367, 0.20530295372009277]
>>> from __future__ import division
>>> T(lambda : 1234567890 / 4).repeat()
[0.14969301223754883, 0.14155197143554688, 0.14141488075256348]
>>> T(lambda : 1234567890 * 0.25).repeat()
[0.13619112968444824, 0.1281130313873291, 0.12830305099487305]
Run Code Online (Sandbox Code Playgroud)

并且:

>>> from math import sqrt
>>> T(lambda : sqrt(1234567890)).repeat()
[0.2597470283508301, 0.2498021125793457, 0.24994492530822754]
>>> T(lambda : 1234567890 ** 0.5).repeat()
[0.15409398078918457, 0.14059877395629883, 0.14049601554870605]
Run Code Online (Sandbox Code Playgroud)

我假设它与C实现python的方式有关,但我想知道是否有人会解释为什么会如此?

c python performance python-2.7 python-internals

79
推荐指数
1
解决办法
5585
查看次数

为什么我可以在Python for循环中为迭代器和序列使用相同的名称?

这更像是一个概念性问题.我最近在Python中看到了一段代码(它在2.7中工作,也可能在2.5中运行),其中一个for循环对迭代的列表和列表中的项使用相同的名称,这既是一种糟糕的做法,也是一种根本不起作用的东西.

例如:

x = [1,2,3,4,5]
for x in x:
    print x
print x
Run Code Online (Sandbox Code Playgroud)

产量:

1
2
3
4
5
5
Run Code Online (Sandbox Code Playgroud)

现在,我觉得打印的最后一个值是从循环中分配给x的最后一个值,但是我不明白为什么你能够为for循环的两个部分使用相同的变量名并且它按预期运作.它们在不同的范围内吗?引擎盖下发生了什么让这样的事情发挥作用?

python for-loop variable-assignment python-internals

78
推荐指数
3
解决办法
4618
查看次数

list()比列表理解使用更多的内存

所以我正在玩list对象,并发现一些奇怪的事情,如果list创建list()它使用更多的内存,而不是列表理解?我正在使用Python 3.5.2

In [1]: import sys
In [2]: a = list(range(100))
In [3]: sys.getsizeof(a)
Out[3]: 1008
In [4]: b = [i for i in range(100)]
In [5]: sys.getsizeof(b)
Out[5]: 912
In [6]: type(a) == type(b)
Out[6]: True
In [7]: a == b
Out[7]: True
In [8]: sys.getsizeof(list(b))
Out[8]: 1008
Run Code Online (Sandbox Code Playgroud)

来自文档:

列表可以通过以下几种方式构建:

  • 使用一对方括号表示空列表: []
  • 使用方括号,用逗号分隔项目:[a],[a, b, c]
  • 使用列表理解: [x for x in iterable]
  • 使用类型构造函数:list()list(iterable)

但似乎使用list()它会占用更多内存. …

python cpython list-comprehension list python-internals

78
推荐指数
2
解决办法
3295
查看次数

为什么代码使用中间变量比没有代码更快?

我遇到了这种奇怪的行为并且无法解释它.这些是基准:

py -3 -m timeit "tuple(range(2000)) == tuple(range(2000))"
10000 loops, best of 3: 97.7 usec per loop
py -3 -m timeit "a = tuple(range(2000));  b = tuple(range(2000)); a==b"
10000 loops, best of 3: 70.7 usec per loop
Run Code Online (Sandbox Code Playgroud)

为什么与变量赋值的比较比使用临时变量的单个衬里快27%以上?

通过Python文档,在timeit期间禁用垃圾收集,因此它不可能.这是某种优化吗?

结果也可以在Python 2.x中重现,但程度较小.

运行Windows 7,CPython 3.5.1,Intel i7 3.40 GHz,64位操作系统和Python.看起来像我尝试在Intel i7 3.60 GHz上使用Python 3.5.0运行的另一台机器不能重现结果.


使用与timeit.timeit()@ 10000循环相同的Python进程运行分别产生0.703和0.804.仍显示尽管程度较轻.(〜12.5%)

python cpython python-3.x python-internals

76
推荐指数
2
解决办法
5388
查看次数

Python中的Integer Cache有什么用?

深入研究Python的源代码后,我发现它维护了一个PyInt_Objects 数组,范围从int(-5)到int(256)(@src/Objects/intobject.c)

一个小实验证明了这一点:

>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False
Run Code Online (Sandbox Code Playgroud)

但是如果我在py文件中一起运行这些代码(或者用分号连接它们),结果会有所不同:

>>> a = 257; b = 257; a is b
True
Run Code Online (Sandbox Code Playgroud)

我很好奇为什么它们仍然是同一个对象,所以我深入研究语法树和编译器,我想出了一个下面列出的调用层次结构:

PyRun_FileExFlags() 
    mod = PyParser_ASTFromFile() 
        node *n = PyParser_ParseFileFlagsEx() //source to cst
            parsetoke() 
                ps = PyParser_New() 
                for (;;)
                    PyTokenizer_Get() 
                    PyParser_AddToken(ps, ...)
        mod = PyAST_FromNode(n, ...)  //cst to ast
    run_mod(mod, ...)
        co = PyAST_Compile(mod, ...) //ast to CFG …
Run Code Online (Sandbox Code Playgroud)

python caching code-analysis literals python-internals

74
推荐指数
1
解决办法
6755
查看次数

为什么这个Python String的大小会在失败的int转换中发生变化

这里推文:

import sys
x = 'ñ'
print(sys.getsizeof(x))
int(x) #throws an error
print(sys.getsizeof(x))
Run Code Online (Sandbox Code Playgroud)

我们得到74,然后是两个getsizeof调用的77个字节.

看起来我们正在从失败的int调用中向对象添加3个字节.

来自twitter的更多示例(您可能需要重新启动python以将大小重置为74):

x = 'ñ'
y = 'ñ'
int(x)
print(sys.getsizeof(y))
Run Code Online (Sandbox Code Playgroud)

77!

print(sys.getsizeof('ñ'))
int('ñ')
print(sys.getsizeof('ñ'))
Run Code Online (Sandbox Code Playgroud)

74,然后77.

python string unicode python-3.x python-internals

71
推荐指数
1
解决办法
3887
查看次数

为什么在迭代时添加到集合和从集合中删除时会得到这么多的迭代?

试图理解 Python for 循环,我认为这会给出{1}一次迭代的结果,或者只是陷入无限循环,这取决于它是否像在 C 或其他语言中那样进行迭代。但实际上两者都没有。

>>> s = {0}
>>> for i in s:
...     s.add(i + 1)
...     s.remove(i)
...
>>> print(s)
{16}
Run Code Online (Sandbox Code Playgroud)

为什么要进行 16 次迭代?结果{16}从何而来?

这是使用 Python 3.8.2。在 pypy 上,它产生了预期的结果{1}

python python-internals

70
推荐指数
3
解决办法
3419
查看次数

为什么在参数列表中使用*args语法的尾随逗号是SyntaxError?

为什么你不能*args在Python中使用尾随逗号?换句话说,这是有效的

>>> f(1, 2, b=4,)
Run Code Online (Sandbox Code Playgroud)

但事实并非如此

>>> f(*(1, 2), b=4,)
  File "<stdin>", line 1
    f(*(1, 2), b=4,)
                   ^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

Python 2和Python 3都是这种情况.

python syntax python-internals

69
推荐指数
2
解决办法
3063
查看次数