标签: cpython

何时使用替代Python发行版?

我已经用Python编程了几年,并且一直使用CPython而不考虑它.我读过的书籍和文档也总是指CPython.

何时使用替代分发(PyPy,Stackless等)是有意义的?

谢谢!

python pypy cpython distribution

5
推荐指数
1
解决办法
318
查看次数

Twisted getPage():请求大量页面时进程内存增长

我正在为contstant(每个30-120秒)编写一个脚本来获取大量URL(Icecast/Shoutcast服务器状态页面)的信息,大约500个网址.它工作正常,但python进程驻留大小不断增长.我确信它会无限增长,因为我让它运行了几个小时,从最初的30Mb开始需要1.2Gb RES.

我简化了脚本以便于理解以下内容:

from twisted.internet import reactor
from twisted.web.client import getPage
from twisted.enterprise import adbapi

def ok(res, url):
    print "OK: " + str(url)
    reactor.callLater(30, load, url)

def error(res, url):
    print "FAIL: " + str(url)
    reactor.callLater(30, load, url)

def db_ok(res):
    for item in res:
        if item[1]:
            print "ADDED: " + str(item[1])
            reactor.callLater(30, load, item[1])

def db_error(res):
    print "Database error: " + str(res)
    reactor.stop()

def load(url):
    d = getPage(url,
                headers={"Accept": "text/html"},
                timeout=30)
    d.addCallback(ok, url)
    d.addErrback(error, url)


dbpool = adbapi.ConnectionPool("MySQLdb", "host", "user", "passwd", …
Run Code Online (Sandbox Code Playgroud)

python memory-leaks cpython twisted

5
推荐指数
1
解决办法
682
查看次数

如何使用Py_AddPendingCall

我有一个嵌入式Python程序,它在C中的一个线程中运行.

当Python解释器切换线程上下文(让控制到另一个线程)时,我希望得到通知,以便我可以执行某些必要的操作.

这似乎Py_AddPendingCall正是我正在寻找的.但是,API文档在这个函数上非常简短,我对应该如何Py_AddPendingCall使用感到困惑.通过阅读文档,我的理解是:

  • 工作线程调用Py_AddPendingCall并分配处理函数.
  • 当Python解释器运行时,只要它控制到另一个线程,它就会调用处理函数
  • 处理程序本身在解释器线程中执行,并获取GIL

我用Google搜索了一些显示如何使用的代码Py_AddPendingCall,但我找不到任何东西.我自己尝试使用它根本行不通.永远不会调用处理程序.

我的工作线程代码:

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>

const char* PYTHON_CODE = 
"while True:\n"
"   for i in range(0,10): print(i)\n"
"\n";

int handler(void* arg)
{
    printf("Pending Call invoked!\n");
    abort();
}

void* worker_thread(void*)
{
    PyGILState_STATE state = PyGILState_Ensure();
    int res = Py_AddPendingCall(&func, nullptr);
    cout << "Result: " << res << endl;
    PyRun_SimpleString(CODE);
    PyGILState_Release(state);

    return 0;
}

int main()
{
    Py_Initialize();
    PyEval_InitThreads();
    PyEval_ReleaseLock();

    pthread_t threads[4];
    for …
Run Code Online (Sandbox Code Playgroud)

c python cpython python-c-api python-3.x

5
推荐指数
1
解决办法
1404
查看次数

为什么我要担心CPython中的线程安全?

据我所知,Global Interpreter Lock只允许一个线程访问解释器并执行字节码.如果是这种情况,那么在任何给定时间,只有一个线程将使用解释器及其内存.

有了这个,我认为排除有种族案例的可能性是公平的,因为没有两个线程可以同时访问解释器的内存,但我仍然看到关于确保数据结构是"线程安全"的警告.它有可能覆盖python解释器的所有实现(如cython),它可以关闭GIL并允许真正的多线程.

我理解线程安全在没有启用GIL的解释器环境中的重要性.但是,对于CPython,为什么在编写多线程python代码时会鼓励线程安全?在CPython环境中可能发生的更糟糕的是什么?

python multithreading cpython thread-safety gil

5
推荐指数
1
解决办法
604
查看次数

考虑到GIL,异步怎么可能不是线程安全的?

异步文档阅读:

大多数异步对象不是线程安全的。您仅应担心在事件循环之外访问对象。

有人可以解释一下还是举一个例子说明如何滥用asyncio导致线程之间共享的对象不同步写入?我认为GIL意味着一次只能有一个线程可以运行解释器,因此解释器中发生的事件(例如读取和写入Python对象)在线程之间是微不足道的同步。

上面引用的第二句话听起来像个线索,但我不确定该怎么做。

我猜想线程可能总是会因释放GIL并决定以任何方式写入Python对象而造成严重破坏,但这不是特定于asyncio的,因此我认为文档不是这里所指的。

这是否可能是异步PEP保留某些异步对象不是线程安全的选项的问题,即使目前在CPython中的实现恰好是线程安全的呢?

python cpython python-multithreading thread-synchronization python-asyncio

5
推荐指数
1
解决办法
634
查看次数

如何识别数学运算符

简单的2 ++ 2如何在Python语言的幕后工作?

如果我们在Python解释器中输入:

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

在这里看一下语法错误,我注意到它是Python设计者设计/实现Python的方式.

据说Python是开源代码,所以我开始更多地探索它.我已经阅读了很多关于Python实现的文章,使用cpython.

所以这里Python编译器很容易识别这些++*%-是运算符.因为它是用C语言编写的.C使用一些直接汇编代码编译器,然后转换为机器代码.

问题1: Python编译器如何识别运算符?(关于词法和解析功能)

问题2:我如何修改Python解释器的这种简单行为,它可以抛出语法错误,使多个运算符与多次运算符相同

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

我已经阅读了cpython的这些文件:compile.c parser.c,readline.c

但是我没有遇到任何关于语法错误的异常处理机制的文件.

更新:

我仍在搜索并等待问题2的任何答案

python cpython compilation operators lexical-analysis

5
推荐指数
1
解决办法
168
查看次数

Python 3.7 math.remainder和%(模运算符)之间的区别

Python 3.7的新增功能中, 我们可以看到有新的math.remainder。它说

返回关于y的x的IEEE 754样式余数。对于有限x和有限非零y,这是差异x - n*y,其中n是最接近商的精确值的整数x / y。如果x / y恰好位于两个连续整数之间,则将最接近的偶数整数用于n。因此,其余部分r = remainder(x, y)始终令人满意abs(r) <= 0.5 * abs(y)

特殊情况遵循IEEE 754:尤其remainder(x, math.inf)是对于任何有限X X和remainder(x, 0)remainder(math.inf, x)提高ValueError任何非NaN的X。如果余数运算的结果为零,则该零将具有与x相同的符号。

在使用IEEE 754二进制浮点的平台上,此操作的结果始终可以精确表示:不引入舍入错误。

但我们也要记住,有一个%符号是

其余 x / y

我们还看到操作员需要注意:

不适用于复数。相反,abs()如果合适,使用转换为浮点数。

我甚至没有尝试过运行python 3.7。

但是我尝试过

Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin …
Run Code Online (Sandbox Code Playgroud)

python math cpython python-3.7

5
推荐指数
1
解决办法
1631
查看次数

默认情况下,使用另一个site-packages目录进行setup.py安装

我将Python嵌入到应用程序中。用户通过以下方式安装软件包或模块时

{...}\myapp\python\python.exe setup.py install
Run Code Online (Sandbox Code Playgroud)

软件包将安装在

{...}\myapp\python\lib\site-packages
Run Code Online (Sandbox Code Playgroud)

Is there any chance to use another directory instead by default?

python install cpython setup.py site-packages

5
推荐指数
1
解决办法
3153
查看次数

仅给定堆栈框架对象解析变量名称

我试图找出是否有可能解决堆栈帧中的变量(如返回inspect.currentframe()).

换句话说,我正在寻找一个功能

def resolve_variable(variable_name, frame_object):
    return value_of_that_variable_in_that_stackframe
Run Code Online (Sandbox Code Playgroud)

例如,请考虑以下代码:

global_var = 'global'

def foo():
    closure_var = 'closure'

    def bar(param):
        local_var = 'local'

        frame = inspect.currentframe()
        assert resolve_variable('local_var', frame) == local_var
        assert resolve_variable('param', frame) == param
        assert resolve_variable('closure_var', frame) == closure_var
        assert resolve_variable('global_var', frame) == global_var

    bar('parameter')

foo()
Run Code Online (Sandbox Code Playgroud)

局部和全局变量平凡通过抬头f_localsf_globals框架对象的属性:

def resolve_variable(variable_name, frame_object):
    try:
        return frame_object.f_locals[variable_name]
    except KeyError:
        try:
            return frame_object.f_globals[variable_name]
        except KeyError:
            raise NameError(varname) from None
Run Code Online (Sandbox Code Playgroud)

但问题是关闭变量.据我所知,它们不存储在像本地和全局变量这样的字典中.更糟糕的是,如果函数实际访问它们,变量只会成为闭包变量(例如通过读取它的值_ = closure_var或者用它来写入它nonlocal closure_var; closure_var = _ …

python cpython stack-frame python-3.x

5
推荐指数
1
解决办法
87
查看次数

How to convert this Python 2.7 code to Python 3?

The following code works in Python 2.7, to dynamically inject local variables into a function scope:

myvars = {"var": 123}

def func():
    exec("")
    locals().update(myvars)
    print(var)

func()
# assert "var" not in globals()
Run Code Online (Sandbox Code Playgroud)

这有点微妙,但是exec语句的存在向编译器指示可以修改本地名称空间。在参考实现中,它将把名称“ locals”的查找从LOAD_GLOBAL op转换为LOAD_NAME op,从而允许添加到本地名称空间。

在Python 3中,它exec变成了函数而不是语句,并且该locals()调用返回了名称空间的副本,其中的修改无效。

您如何在Python 3中重新创建想法,以便在函数内部动态创建局部变量?还是仅在Python 2.x中才有“功能”?

注意:该代码不得在外部范围内绑定名称。

python cpython local-variables python-2.7 python-3.x

5
推荐指数
1
解决办法
91
查看次数