我并没有在CPython的上下文中得到"字节码解释器"的概念.有人可以对整个画面有所了解吗?
这是否意味着CPython将编译并执行pyc文件(字节码文件?).那么编译py文件到pyc文件是什么?Jython与CPython有什么不同(除了它们用不同的语言实现).
我还在某处读过Python是C++的解释.它是否正确?这意味着什么?
我对Python仍然很陌生,所以如果我问一些愚蠢的问题,请原谅我......非常感谢你!
我了解到,在一些一成不变的类,__new__可能会返回一个现有实例-这是什么int,str以及tuple各类有时小的值做.
但为什么以下两个片段的行为不同?
最后有一个空格:
>>> a = 'string '
>>> b = 'string '
>>> a is b
False
Run Code Online (Sandbox Code Playgroud)
没有空间:
>>> c = 'string'
>>> d = 'string'
>>> c is d
True
Run Code Online (Sandbox Code Playgroud)
为什么空间带来了差异?
我正在编写一个Python模块来在O_DIRECT上下文中执行IO.O_DIRECT的一个限制是你必须读入对应于2.4和2.5内核的4096字节边界的缓冲区,2.6及以上将接受512的任意倍数.
对此明显的内存分配候选是 posix_memalign(void **memptr, size_t alignment, size_t size)
在我的代码中,我分配了一个像这样的区域:
char *buffer = NULL;
int mem_ret = posix_memalign((void**)&buffer, alignment, size);
if (!buffer) {
PyErr_NoMemory();
return NULL;
}
/* I do some stuff here */
free(buffer);
Run Code Online (Sandbox Code Playgroud)
当我用python3.2编译和导入模块时,这个(以及未示出的模块的其余部分)工作正常.
当我尝试使用python2.7(我想保持兼容性)时,它会抛出PyErr_NoMemory异常,并mem_ret == ENOMEM指示它无法分配.
为什么我编译的Python版本会影响posix_memalign的运行方式?
操作系统:Ubuntu 12.04 LTS
编译器:Clang + GCC显示相同的行为
UPDATE
我现在有了一段代码,感谢user694733
但是它的工作原理使我更加困惑:
#if PY_MAJOR_VERSION >= 3
char *buffer = NULL;
int mem_ret = posix_memalign((void**)&buffer, alignment, count);
#else
void *mem = NULL;
int mem_ret = posix_memalign(&mem, alignment, count);
char *buffer = (char*)mem;
#endif …Run Code Online (Sandbox Code Playgroud) 为什么,在CPython中呢
def add_string(n):
s = ''
for _ in range(n):
s += ' '
Run Code Online (Sandbox Code Playgroud)
需要线性时间,但是
def add_string_in_list(n):
l = ['']
for _ in range(n):
l[0] += ' '
Run Code Online (Sandbox Code Playgroud)
采取二次时间?
证明:
Timer(partial(add_string, 1000000)).timeit(1)
#>>> 0.1848409200028982
Timer(partial(add_string, 10000000)).timeit(1)
#>>> 1.1123797750042286
Run Code Online (Sandbox Code Playgroud)
Timer(partial(add_string_in_list, 10000)).timeit(1)
#>>> 0.0033865350123960525
Timer(partial(add_string_in_list, 100000)).timeit(1)
#>>> 0.25131178900483064
Run Code Online (Sandbox Code Playgroud)
当添加的字符串的引用计数为1时,CPython会对字符串添加进行优化.
这是因为Python中的字符串是不可变的,因此通常无法编辑它们.如果字符串存在多个引用并且它已被突变,则两个引用都将看到更改的字符串.这显然不是必需的,因此多个引用不会发生突变.
但是,如果只有一个对字符串的引用,那么改变该值只会更改该一个引用的字符串,这需要更改它.您可以测试这可能是因为:
from timeit import Timer
from functools import partial
def add_string_two_references(n):
s = ''
for _ in range(n):
s2 = s
s += ' '
Timer(partial(add_string_two_references, 20000)).timeit(1)
#>>> …Run Code Online (Sandbox Code Playgroud) 我在这里的官方cpython代码链接上的说明如下.我做了一个
hg update 3.5
Run Code Online (Sandbox Code Playgroud)
然后做了以下.
sudo apt-get build-dep python3.5
Run Code Online (Sandbox Code Playgroud)
但它引发了一个错误,说明下面列出的语句:
Reading package lists... Done
Picking 'python3-defaults' as source package instead of 'python3'
E: Unable to find a source package for python3
Run Code Online (Sandbox Code Playgroud)
我确实读到了关于减少版本和尝试上面的代码集的问题,这也是因为以下原因引起的.
$ hg update 2.7
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ sudo apt-get build-dep python2.7
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may …Run Code Online (Sandbox Code Playgroud) 我有这样的文件:
documents = [
"I work on c programing.",
"I work on c coding.",
]
Run Code Online (Sandbox Code Playgroud)
我有同义词文件,如:
synonyms = {
"c programing": "c programing",
"c coding": "c programing"
}
Run Code Online (Sandbox Code Playgroud)
我想替换我编写此代码的所有同义词:
# added code to pre-compile all regex to save compilation time. credits alec_djinn
compiled_dict = {}
for value in synonyms:
compiled_dict[value] = re.compile(r'\b' + re.escape(value) + r'\b')
for doc in documents:
document = doc
for value in compiled_dict:
lowercase = compiled_dict[value]
document = lowercase.sub(synonyms[value], document)
print(document)
Run Code Online (Sandbox Code Playgroud)
输出:
I work on c …Run Code Online (Sandbox Code Playgroud) 我正在做一些关于列表上的操作速度的实验。为此,我定义了两个列表:l_short = []和l_long = list(range(10**7))。
这个想法是bool(l)与len(l) != 0
在if比赛中,下面的实现是快了很多if l: pass,而不是if len(l) != 0: pass
但是没有if竞赛,我得到了以下结果:
%%timeit
len(l_long) != 0
# 59.8 ns ± 0.358 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%%timeit
bool(l_long)
# 63.3 ns ± 0.192 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Run Code Online (Sandbox Code Playgroud)
的时间bool稍长,为什么呢?
这是使用dis(FYI)的字节码
dis("len(l_long) != 0")
""" …Run Code Online (Sandbox Code Playgroud) Python 3.8(或 CPython 3.8?)添加了警告
SyntaxWarning: "is" with a literal. Did you mean "=="?
Run Code Online (Sandbox Code Playgroud)
对于代码0 is 0。
我理解的警告,我知道之间的区别is和==。
但是,我也知道 CPython 会缓存小整数的对象并在其他情况下共享它。(出于好奇,我再次检查了代码(标头)。小整数被缓存在tstate->interp->small_ints. 中
0,1并且更加特殊,并且全局存储在_PyLong_Zero和 中_PyLong_One。所有新创建的ints 都是 viaPyLong_FromLong并且首先检查它是否是一个小整数整数和缓存。)
鉴于这种背景,如果你知道你有一个int对象,你可以说支票x is 0应该是安全的,对吧?此外,您可以推导出0 is 0应该始终是True,对吗?或者这是 CPython 的一个实现细节而其他解释器没有遵循这个?哪个解释器不遵循这个?
尽管这个更通用的问题(我只是好奇),请考虑这个更具体的(示例)代码:
def sum1a(*args):
y = 0
for x in args:
if y is 0:
y = x …Run Code Online (Sandbox Code Playgroud) 如果使用-i选项调用cpython解释器,它将在完成运行的任何命令或脚本后进入交互模式.有没有办法在一个程序中让解释器执行此操作,即使它没有给出-i?明显的用例是在发生异常情况时通过交互式检查状态进行调试.
从这个链接我了解到了
当前实现为-5到256之间的所有整数保留一个整数对象数组,当您在该范围内创建一个int时,实际上只返回对现有对象的引用
但是当我尝试为我的会话提供一些示例时,我发现它在赋值和元组解包时表现不同.
这是片段,
Python 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a,b = 300,300
>>> a is b
True
>>> c = 300
>>> d = 300
>>> c is d
False
>>>
Run Code Online (Sandbox Code Playgroud) cpython ×10
python ×9
python-3.x ×2
string ×2
bytecode ×1
c ×1
c++ ×1
immutability ×1
interpreter ×1
optimization ×1
performance ×1
python-2.7 ×1
ubuntu-16.04 ×1
word2vec ×1