这是 Python 中的一个简单的线性同余生成器:
def prng(n):
# https://en.wikipedia.org/wiki/Lehmer_random_number_generator
while True:
n = n * 48271 % 0x7fffffff
yield n
g = prng(123)
for i in range(10**8):
next(g)
assert next(g) == 1062172093
Run Code Online (Sandbox Code Playgroud)
Python 2.7 比任何版本的 Python 3.x 都快。在 Linux 上生成 100M 项:
python2.7 g.py 14.60s user 0.65s system 99% cpu 15.260 total
python3.6 g.py 18.70s user 0.00s system 99% cpu 18.711 total
python3.7 g.py 18.10s user 0.04s system 99% cpu 18.193 total
python3.8 g.py 19.22s user 0.02s system 99% cpu …Run Code Online (Sandbox Code Playgroud) 下面是在builtins.pyi
def max(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsLessThan]) -> _T:
Run Code Online (Sandbox Code Playgroud)
我确实知道名称修饰的含义,并且知道名称修饰将影响类定义字段中的每个“__xxx”标识符。
所以我有三个问题:
非常感谢。
进一步的工作:
def wat1(__a):
def wat2(__b):
return __b, __a
return __a
print(wat1.__code__.co_varnames)
print(wat1.__code__.co_cellvars)
dis.dis(wat1)
Run Code Online (Sandbox Code Playgroud)
输出(linux python==3.10.8):
('__a', 'wat2')
('__a',)
21 0 LOAD_FAST 0 (__a)
2 RETURN_VALUE
22 0 LOAD_FAST 0 (__b)
2 LOAD_DEREF 0 (__a)
4 BUILD_TUPLE 2
6 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud) 不确定这是否偏离主题,但不知道有什么更好的地方可以问。其中cpython有一个非常巨大的switch case语句用于执行每个操作码。此开关盒先前已放置在_PyEval_EvalFrameDefault函数中。链接在这里。switch case 语句从这里开始。这是 cpython 的核心部分,每个对 cpython 内部结构感兴趣的人可能都会详细探索它。最近我在找它,但没有找到。在这个版本中_PyEval_EvalFrameDefault我找不到它。比上一篇短多了。我什至尝试通过在 IDE 中搜索操作码来找到此 switch 语句。但即便如此也无助于找到它在哪里。任何了解最新 cpython 开发变化的人都可以帮助我吗?提前致谢。
在询问有关反思的问题时,我问:
很好的答案.但说
myobject.foo()和之间有区别x = getattr(myobject, "foo"); x();.即使它只是化妆品.在第一个中,foo()是静态编译的.在第二种情况下,字符串可以通过多种方式生成. - 乔1小时前
得到了答案:
呃,马铃薯/马铃薯...在python中,niether是静态编译的,所以它们或多或少相当. - SWeko 1小时前
我知道Python对象的成员存储在字典中,并且一切都是动态的,但我假设给出了以下代码:
class Thing():
def m(self):
pass
t = Thing()
Run Code Online (Sandbox Code Playgroud)
生成.pyc时,以下代码会以某种方式静态编译:
t.m()
Run Code Online (Sandbox Code Playgroud)
即编译器知道地址m(),因此在运行时没有点绑定.那个或运行时会缓存后续查找.
虽然这总是涉及到字典:
meth = getattr(t, "m")
meth()
Run Code Online (Sandbox Code Playgroud)
是否所有调用都被视为字典中的字符串查找?或者这两个例子实际上是相同的吗?
我非常喜欢D(2)语言,并希望将它用于多平台GUI应用程序,但我发现它的生态系统还没有完全发展.从Linux迁移到(Free)PC-BSD之后,我发现在端口中甚至没有准备好64位编译器,并且不确定是否有任何GUI库(QtD,gtkD,wxD)已准备好用于严肃的项目,我们希望尽快开始项目.
Otoh,我之前被推荐尝试使用Python,这是成熟的,有很多工具,GUI库等等但是有关于速度的问题 - 我们必须使用一个C lib来计算Ephemeris并编写几个可以使用该C-lib的库.
然而,对于Cython来说这可能是一个很好的(完美的)工作,所以我的问题是你如何考虑在Python(Qt,EFL)中编写GUI部分并使用Cython来处理性能关键的东西(绑定外部C lib并编写我们自己的图书馆)而不是(等待)D为严肃的项目做好准备?
在CPython中,线程模块不使用多个内核,因为它使用全局解释器锁.但是我最近发现标准库中的多处理模块据说可以回避GIL.所以我认为使用该模块可以在CPython中正确使用多个核心,但我想知道我是否正确.
我需要编写一个需要很好地利用多个内核的应用程序,但这不是性能关键所以我可以用Python编写它,但我需要知道这个模块是否允许我使用多个内核?
int.__hash__简单地返回值似乎是合理的。果然,这似乎是CPython实现它的方式:
>>> hash(1)
1
>>> hash(2)
2
>>> hash(123456789)
123456789
>>> hash(-123456789)
-123456789
Run Code Online (Sandbox Code Playgroud)
好吧,这对于所有大多数整数x都成立吗?
>>> [x for x in range(-10000, 10000) if hash(x) != x]
[-1]
Run Code Online (Sandbox Code Playgroud)
??
>>> hash(-1)
-2
Run Code Online (Sandbox Code Playgroud)
为什么是-1该规则的例外?
我在git(第25行)看_math.c:
#if !defined(HAVE_ACOSH) || !defined(HAVE_ASINH)
static const double ln2 = 6.93147180559945286227E-01;
static const double two_pow_p28 = 268435456.0; /* 2**28 */
Run Code Online (Sandbox Code Playgroud)
我注意到ln2值与ln2的wolframalpha值不同.(光头部分是差异)
ln2 = 0.693147180559945 286227(cpython)
ln2 = 0.693147180559945 3094172321214581(wolframalpha)
ln2 = 0.693147180559945 309417232121458(维基百科)
所以我的问题是为什么会有区别?我错过了什么?
我发现_datetimemodule.c哪个似乎是正确的文件,但我需要一些帮助,因为C不是我的力量.
>>> import datetime
>>> import sys
>>> d = datetime.datetime.now()
>>> sys.getsizeof(d)
48
>>> d = datetime.datetime(2018, 12, 31, 23, 59, 59, 123)
>>> sys.getsizeof(d)
48
Run Code Online (Sandbox Code Playgroud)
因此,时区不知道的日期时间对象需要48个字节.看着PyDateTime_DateTimeType,它似乎是一个PyDateTime_DateType和一个PyDateTime_TimeType.也许_PyDateTime_BaseTime呢?
通过查看代码,我的印象是每个字段都存储了一个组件YYYY-mm-dd HH:MM:ss,意思是:
int16_t16位)int8_tint8_tint8_tint8_tint8_tuint16_t但是,这将是2*16 + 5*8 = 72位= 9字节而不是48字节,因为Python告诉我.
我对datetime内部结构的假设在哪里错了?我怎么能在代码中看到这个?
(我想这可能在Python实现之间有所不同 - 如果是这样,请关注cPython)
Cpython优化字符串增量操作,在为字符串初始化内存时,程序为其留下额外的扩展空间,因此,在递增时,原始字符串不会复制到新位置.我的问题是为什么字符串变量的id会发生变化.
>>> s = 'ab'
>>> id(s)
991736112104
>>> s += 'cd'
>>> id(s)
991736774080
Run Code Online (Sandbox Code Playgroud)
为什么string变量的id改变了.
cpython ×10
python ×10
python-3.x ×2
biginteger ×1
binding ×1
c ×1
cython ×1
d ×1
datetime ×1
hash ×1
memory ×1
performance ×1