我必须使用商业Java库,并希望从Python中完成.Jython很强大,我很好,因为它背后有一些点发布.但是,我也想使用NumPy,这显然不适用于Jython.CPype和Java数字库之类的选项没有吸引力.前者基本上死了.后者大多不成熟,缺乏易用性和广泛接受NumPy.我的问题是:如何让Jython和Python代码互操作?我可以接受从Cpython或其他方式调用Jython.
我想要一个可以生成伪随机值序列的函数,但是每次运行时该序列都是可重复的.我想要的数据必须在给定范围内相当好地随机分布,它不一定是完美的.
我想编写一些基于随机数据运行性能测试的代码.我希望每台机器上的每次测试运行的数据都是相同的,但我不希望出于存储原因而将测试随机数据发送出去(最终可能会导致很多兆字节).
该random模块的库似乎并不表示相同的种子将始终在任何计算机上提供相同的序列.
编辑:如果您打算建议我播种数据(如上所述),请提供说明该方法有效的文档,并将适用于一系列机器/实现.
编辑:Mac OS X上的CPython 2.7.1和PyPy 1.7以及CPython 2.7.1和CPython 2.52 = .2 Ubuntu似乎给出了相同的结果.尽管如此,还没有任何文件以黑白方式规定这一点.
有任何想法吗?
Python C API函数PyEval_EvalCode允许您执行已编译的Python代码.我想执行一段Python代码,就像它在函数范围内执行一样,因此它有自己的局部变量字典,不会影响全局状态.
这看起来很容易,因为PyEval_EvalCode您可以提供全局和本地词典:
PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
我遇到的问题与Python如何查找变量名称有关.考虑以下代码,我执行PyEval_EvalCode:
myvar = 300
def func():
return myvar
func()
Run Code Online (Sandbox Code Playgroud)
这个简单的代码实际上会引发错误,因为Python无法myvar从内部找到变量func.即使myvar在外部作用域中的本地字典中,Python也不会将其复制到内部作用域中的本地字典中.原因如下:
每当Python查找变量名时,首先检查locals,然后检查globals,最后检查builtins.在模块范围,locals并且globals是SAME字典对象.因此,声明x = 5在模块范围内将放置x在该locals字典,这也是globals字典.现在,在函数范围内x找不到需要查找的模块作用域定义x的函数locals,因为Python不会将模块作用域本地复制到函数作用域本地.但是,这通常是没有问题的,因为它可以找到x在globals.
x = 5
def foo():
print(x) # This works because 'x' in …Run Code Online (Sandbox Code Playgroud) Python的print声明通常似乎打印repr()其输入.元组似乎不是例外:
>>> print (1, 2, 3)
(1, 2, 3)
>>> print repr((1, 2, 3))
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
但是当我弄乱CPython的内部时,我偶然发现了一些奇怪的行为.简而言之:如果您使用Python 2来创建自引用元组,则直接打印它的行为与打印其repr()/ str()/ unicode()表示完全不同.
>>> print outer # refer to the link above
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
... many lines later ...
((((((((((Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError: stack overflow
>>> print repr(outer)
((...),)
>>> print str(outer)
((...),)
>>> print unicode(outer)
((...),)
Run Code Online (Sandbox Code Playgroud)
到底是print做什么的?为了尝试自己回答这个问题,我提到了语言参考:
6.6.该
print …
为什么使用切片对列表进行浅层复制比使用list内置更快?
In [1]: x = range(10)
In [2]: timeit x_ = x[:]
10000000 loops, best of 3: 83.2 ns per loop
In [3]: timeit x_ = list(x)
10000000 loops, best of 3: 147 ns per loop
Run Code Online (Sandbox Code Playgroud)
通常当我看到这样奇怪的事情时,它们在python3中被修复 - 但这种差异仍然存在:
In [1]: x = list(range(10))
In [2]: timeit x_ = x[:]
10000000 loops, best of 3: 100 ns per loop
In [3]: timeit x_ = list(x)
10000000 loops, best of 3: 178 ns per loop
Run Code Online (Sandbox Code Playgroud) CPython线程支持的文档是令人沮丧的矛盾和稀疏.
通常,似乎每个人都同意嵌入Python的多线程C应用程序必须始终在调用Python解释器之前获取GIL.通常,这通过以下方式完成:
PyGILState_STATE s = PyGILState_Ensure();
/* do stuff with Python */
PyGILState_Release(s);
Run Code Online (Sandbox Code Playgroud)
这些文档很明显地说明了这一点:https://docs.python.org/2/c-api/init.html#non-python-created-threads
但是,在实践中,获得一个嵌入Python实际工作顺利的多线程C程序是另一回事.即使您完全遵循文档,似乎也有很多怪癖和惊喜.
例如,似乎在幕后,Python区分"主线程"(我猜是调用的线程Py_Initialize)和其他线程.具体来说,任何尝试获取GIL并在"主"线程中运行Python代码的尝试一直都失败了 - 当我尝试这样做时 - (至少使用Python 3.x),程序会中止一条Fatal Python error: drop_gil: GIL is not locked消息,这很愚蠢,因为当然GIL被锁定了!
例:
int main()
{
Py_Initialize();
PyEval_InitThreads();
PyEval_ReleaseLock();
assert(PyEval_ThreadsInitialized());
PyGILState_STATE s = PyGILState_Ensure();
const char* command = "x = 5\nfor i in range(0,10): print(x*i)";
PyRun_SimpleString(command);
PyGILState_Release(s);
Py_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个简单的程序以"GIL未锁定错误"中止,即使我明确锁定它.但是,如果我生成另一个线程,并尝试在该线程中获取GIL,一切正常.
所以CPython似乎有一个(未记录的)"主线程"概念,它与C产生的辅助线程有某种不同.
问题:这是否记录在任何地方?有没有人有任何经验可以说明获取GIL的具体规则是什么,如果处于"主要"线程而不是子线程应该对此有任何影响?
PS:另外,我已经注意到这PyEval_ReleaseLock是一个弃用的API调用,但我还没有看到任何实际可行的替代方案.如果您在通话PyEval_ReleaseLock后没有打电话PyEval_InitThreads,您的程序会立即挂起.然而,在该文档中提到的新的替代方案,PyEval_SaveThread …
所以它是一个CPython的东西,不太确定它与其他实现有相同的行为.
但'{0}'.format()比str()和更快'{}'.format().我发布了Python 3.5.2的结果,但是,我尝试使用Python 2.7.12并且趋势是相同的.
%timeit q=['{0}'.format(i) for i in range(100, 100000, 100)]
%timeit q=[str(i) for i in range(100, 100000, 100)]
%timeit q=['{}'.format(i) for i in range(100, 100000, 100)]
1000 loops, best of 3: 231 µs per loop
1000 loops, best of 3: 298 µs per loop
1000 loops, best of 3: 434 µs per loop
Run Code Online (Sandbox Code Playgroud)
从文档上object.__str__(self)
由
str(object)内置函数调用format()并print()计算对象的"非正式"或可打印的字符串表示形式.
所以,str()并format() …
我试图制作一个纯python(没有外部依赖)两个序列的元素比较.我的第一个解决方案是
list(map(operator.eq, seq1, seq2))
Run Code Online (Sandbox Code Playgroud)
然后我发现了starmap函数itertools,这看起来和我很相似.但在最坏的情况下,我的计算机上的速度提高了37%.由于对我来说不是很明显,我测量了从生成器中检索1个元素所需的时间(不知道这种方式是否正确):
from operator import eq
from itertools import starmap
seq1 = [1,2,3]*10000
seq2 = [1,2,3]*10000
seq2[-1] = 5
gen1 = map(eq, seq1, seq2))
gen2 = starmap(eq, zip(seq1, seq2))
%timeit -n1000 -r10 next(gen1)
%timeit -n1000 -r10 next(gen2)
271 ns ± 1.26 ns per loop (mean ± std. dev. of 10 runs, 1000 loops each)
208 ns ± 1.72 ns per loop (mean ± std. dev. of 10 runs, 1000 loops each)
Run Code Online (Sandbox Code Playgroud)
在检索元素时,第二种解决方案的性能提高了24%.在那之后,他们都产生相同的结果list …
How efficient is python (cpython I guess) when allocating resources for a newly created instance of a class? I have a situation where I will need to instantiate a node class millions of times to make a tree structure. Each of the node objects should be lightweight, just containing a few numbers and references to parent and child nodes.
For example, will python need to allocate memory for all the "double underscore" properties of each instantiated object (e.g. the docstrings, …
CPython 3.6.4:
from functools import partial
def add(x, y, z, a):
return x + y + z + a
list_of_as = list(range(10000))
def max1():
return max(list_of_as , key=lambda a: add(10, 20, 30, a))
def max2():
return max(list_of_as , key=partial(add, 10, 20, 30))
Run Code Online (Sandbox Code Playgroud)
现在:
In [2]: %timeit max1()
4.36 ms ± 42.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [3]: %timeit max2()
3.67 ms ± 25.9 µs per loop (mean ± std. dev. of …Run Code Online (Sandbox Code Playgroud) cpython ×10
python ×10
performance ×3
c ×2
python-3.x ×2
class ×1
functools ×1
instance ×1
java ×1
jython ×1
list ×1
numpy ×1
python-2.7 ×1
python-c-api ×1
random ×1
shallow-copy ×1