标签: python-internals

如何在CPython中实现元组?

我一直在努力学习如何在幕后实现CPython.Python很高级很棒,但我不喜欢把它当成黑盒子.

考虑到这一点,元组是如何实现的?我已经看过了源码(tupleobject.c),但它已经过了我的脑海.

我看到的PyTuple_MAXSAVESIZE = 20PyTuple_MAXFREELIST = 2000,什么是节约型和"自由列表"?(长度为20/21或2000/2001的元组之间是否存在性能差异?什么强制实现最大元组长度?)

python tuples cpython data-structures python-internals

25
推荐指数
2
解决办法
5192
查看次数

如何定义Python模块中的__name__变量?

我知道标准的例子:如果你直接执行一个模块,那么它的__name__全局变量定义为"__main__".但是,在文档中没有任何地方可以找到__name__在一般情况下如何定义的精确描述.该模块的文件说...

在模块中,模块的名称(作为字符串)可用作全局变量的值__name__.

......但是"模块名称"是什么意思?它只是模块的名称(已.py删除的文件名),还是包含完全限定的包名称?

如何__name__确定Python模块中变量的值?对于奖励积分,请准确指出在Python源代码中执行此操作的位置.

python python-module python-internals

25
推荐指数
1
解决办法
2万
查看次数

为什么从模块导入函数比整个模块本身需要更长的时间?

考虑:

>>> timeit.timeit('from win32com.client import Dispatch', number=100000)
0.18883283882571789
>>> timeit.timeit('import win32com.client', number=100000)
0.1275979248277963
Run Code Online (Sandbox Code Playgroud)

仅导入Dispatch函数而不是整个模块需要更长的时间,这似乎是反直觉的.有人可以解释为什么单一功能的开销是如此糟糕?谢谢!

python performance python-import python-internals

25
推荐指数
2
解决办法
1237
查看次数

为什么int需要三倍于Python的内存?

在64位系统上,Python中的整数需要24个字节.这是例如C对于64位整数所需的内存的3倍.现在,我知道这是因为Python整数是对象.但是用于什么额外的内存?我有猜测,但肯定知道这会很好.

python memory int object python-internals

25
推荐指数
1
解决办法
3127
查看次数

在'if'子句中使用'in'时的元组或列表?

哪种方法更好?使用元组,如:

if number in (1, 2):
Run Code Online (Sandbox Code Playgroud)

或列表,如:

if number in [1, 2]:
Run Code Online (Sandbox Code Playgroud)

推荐哪一种用于此类用途以及为什么(逻辑和性能都明智)?

python optimization tuples list python-internals

25
推荐指数
1
解决办法
1256
查看次数

标识符规范化:为什么微标志转换为希腊字母mu?

我偶然发现了以下奇怪的情况:

>>> class Test:
        µ = 'foo'

>>> Test.µ
'foo'
>>> getattr(Test, 'µ')
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    getattr(Test, 'µ')
AttributeError: type object 'Test' has no attribute 'µ'
>>> 'µ'.encode(), dir(Test)[-1].encode()
(b'\xc2\xb5', b'\xce\xbc')
Run Code Online (Sandbox Code Playgroud)

我输入的字符始终是键盘上的μ符号,但由于某种原因它会被转换.为什么会这样?

python unicode identifier python-3.x python-internals

25
推荐指数
1
解决办法
792
查看次数

为什么Python 2.7中的dict定义比Python 3.x更快?

我遇到过一种(非常不寻常的)情况,我不得不使用一个map()或一个列表推导表达式.然后我想知道哪一个更快.

这个 StackOverflow答案为我提供了解决方案,但后来我开始自己测试.基本上结果是一样的,但是我在切换到Python 3时发现了一个意外的行为,我很好奇,即:

? iulian-pc ~ ? python --version
Python 2.7.6
? iulian-pc ~ ? python3 --version
Python 3.4.3

? iulian-pc ~ ? python -mtimeit '{}'                                                     
10000000 loops, best of 3: 0.0306 usec per loop
? iulian-pc ~ ? python3 -mtimeit '{}'                
10000000 loops, best of 3: 0.105 usec per loop

? iulian-pc ~ ? python -mtimeit 'dict()'
10000000 loops, best of 3: 0.103 usec per loop
? iulian-pc ~ ? python3 -mtimeit 'dict()'
10000000 loops, best …
Run Code Online (Sandbox Code Playgroud)

python dictionary python-2.7 python-3.x python-internals

25
推荐指数
3
解决办法
1801
查看次数

为什么Python列表添加必须是同质的?

任何熟悉Python内部(CPython或其他实现)的人都可以解释为什么列表添加需要是同质的:

In [1]: x = [1]

In [2]: x+"foo"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\Users\Marcin\<ipython-input-2-94cd84126ddc> in <module>()
----> 1 x+"foo"

TypeError: can only concatenate list (not "str") to list

In [3]: x+="foo"

In [4]: x
Out[4]: [1, 'f', 'o', 'o']
Run Code Online (Sandbox Code Playgroud)

为什么x+"foo"以上不会返回与x上述成绩单中的最终值相同的值?

这个问题来自NPE的问题:Python列表+ = iterable的行为是否记录在何处?

更新:我知道不需要异质+=工作(但确实如此),同样,并不要求异质+是错误.这个问题是为什么做出后一种选择.

很难说将序列添加到列表中的结果是不确定的.如果这是一个充分的反对意见,那么防止异质性是有意义的+=.Update2:特别是,python总是将操作符调用委托给左侧操作数,因此没有问题出现"什么是正确的事情"":左手对象总是管理(除非它委托到右边).

更新3:对于任何人认为这是一个设计决定,请解释(a)为什么没有记录; 或(b)如有文件记录.

Update4:"应该[1] + (2, )返回什么?" 它应该返回一个结果值,该值等于x最初[1]紧跟在之后的变量的值x+=(2, ).这个结果定义明确.

python language-design language-implementation python-internals

24
推荐指数
2
解决办法
817
查看次数

self = None是做什么的?

我正在阅读传入asyncio包的源代码.请注意,在方法的最后,有一个self = None声明.它有什么作用?

def _run(self):
    try:
        self._callback(*self._args)
    except Exception as exc:
        msg = 'Exception in callback {}{!r}'.format(self._callback,
                                                    self._args)
        self._loop.call_exception_handler({
            'message': msg,
            'exception': exc,
            'handle': self,
        })
    self = None  # Needed to break cycles when an exception occurs.
Run Code Online (Sandbox Code Playgroud)

我认为它会删除实例,但以下测试不建议如此:

class K:
    def haha(self):
        self = None

a = K()
a.haha()
print(a) # a is still an instance
Run Code Online (Sandbox Code Playgroud)

python garbage-collection python-internals python-asyncio

24
推荐指数
1
解决办法
4736
查看次数

致命的Python错误和`BufferedWriter`

我在文件中发现了这一段,其中说:

二进制缓冲对象(的实例BufferedReader,BufferedWriter,BufferedRandomBufferedRWPair)使用锁保护它们的内部结构; 因此,可以安全地从多个线程一次调用它们.

鉴于GIL正在行动,我不确定为什么他们需要"保护"他们的内部结构.谁在乎?在我发现这个锁具有一定意义之前我并不在意,考虑这段代码:

from _thread import start_new_thread
import time

def start():
    for i in range(10):
        print("SPAM SPAM SPAM!")

for i in range(10):
    start_new_thread(start, ())

time.sleep(0.0001)
print("main thread exited")
Run Code Online (Sandbox Code Playgroud)

在Python 3.X上运行时的输出:

...many SPAM...
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
main thread exited
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
Fatal Python error: could not acquire lock for 
<_io.BufferedWritername='<stdout>'> at interpreter shutdown, …
Run Code Online (Sandbox Code Playgroud)

python linux multithreading python-2.7 python-internals

24
推荐指数
2
解决办法
3993
查看次数