我有一个在此函数中创建的lambda对象:
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
self.record(lambda s:
s.add_url_rule(rule, endpoint, view_func, **options))
Run Code Online (Sandbox Code Playgroud)
使用func_closurelambda函数对象,我可以访问lambda函数的闭包范围:
(<cell at 0x3eb89f0: str object at 0x2fb4378>,
<cell at 0x3eb8a28: function object at 0x3cb3a28>,
<cell at 0x3eb8a60: str object at 0x3ebd090>,
<cell at 0x3eb8b08: dict object at 0x3016ec0>)
Run Code Online (Sandbox Code Playgroud)
仔细观察(cell_contents每个cell对象的属性)向我展示:
>>> [c.cell_contents for c in func.func_closure]
['categoryDisplay',
<function indico.web.flask.util.RHCategoryDisplay>,
'/<categId>/',
{}]
Run Code Online (Sandbox Code Playgroud)
lambda函数是由这个调用创建的:
add_url_rule('/<categId>/', 'categoryDisplay', rh_as_view(RHCategoryDisplay))
Run Code Online (Sandbox Code Playgroud)
如您所见,顺序与函数的参数顺序或lambda中使用参数的顺序不匹配.虽然我可以根据其类型/内容轻松找出哪个元素是什么,但我想以更清洁的方式进行.
所以我的问题是:如何将它与原始变量名称相关联(或者至少在函数参数的情况下位置)?
看看这个Python代码:
from gc import get_referrers as refs
x = 'x'
d = {x:x}
print(d in refs(x))
Run Code Online (Sandbox Code Playgroud)
它打印False.这本身就很奇怪,但是当你考虑以下因素时变得更加怪异:
如果x是一个数字(int,float,complex,Fraction,Decimal)而不是字符串,它仍然会打印False.对于字节和bytearray也是如此.但是对于其他所有类型(如果用作键,可以使用,如tuple或frozenset,还有许多其他类型,如果仅用作值),则会打印True.
如果d是包含x的任何其他容器(set,list,tuple ...),则输出True.只有dict,它打印False.此外,如果x是键或值,或者如上所述,两者都无关紧要.
我认为在Python中,每个对象都是一个引用(而不是Java,它有原始类型,或者Ruby,它是值类型小的int),但现在看起来str和int是有点原始的类型,没有被引用.但另一方面,为什么只有在说?
我也知道在CPython中缓存了从-5到256的整数(并且可以实现小字符串),因此不重新计算它们是有意义的,因为它们永远不会被删除,但这适用于任何整数(和长字符串)我试过,比那个范围大得多.
有谁知道这里发生了什么?
---更新---
Curiouser和curiouser ......似乎是datetime.{datetime,date,time}类具有相同的"未引用"行为.现在,我知道有一件事,AnyStr和Number有一个共同点:他们的哈希值是随机的,每个会话的盐.但这没有任何意义,因为即使这些行为仅仅是词汇中的值而不是键,也会观察到行为.价值观并没有散播.或者是他们?
所以最近我理解了函数闭包的概念.
def outer():
somevar = []
assert "somevar" in locals() and not "somevar" in globals()
def inner():
assert "somevar" in locals() and not "somevar" in globals()
somevar.append(5)
return somevar
return inner
function = outer()
somevar_returned = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)
Run Code Online (Sandbox Code Playgroud)
根据我的理解,函数闭包的目的是保持对对象的活动引用,以避免垃圾收集此对象.这就是为什么以下工作正常:
del outer
somevar_returned_2 = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)
assert id(somevar_returned) == id(somevar_returned_2)
Run Code Online (Sandbox Code Playgroud)
在执行inner函数之前,事情是(总是和我理解的一样),Python重建了locals变量字典.这本词典将包含:
问题是Python存储闭包的名称绑定在哪里?我找不到任何地方.
注意:函数的属性:
>>> print "\n".join("%-16s : %s" % (e, getattr(function, e)) for e in dir(function) if not e.startswith("_") and e …Run Code Online (Sandbox Code Playgroud) 在Python 2.7,3.4和3.5中,grp.getgrgid能够接受一个字符串:
from grp import getgrgid
print(getgrgid('0'))
Run Code Online (Sandbox Code Playgroud)
但是,pwd.getpwuid不能这样做:
from pwd import getpwuid
print(getpwuid('0'))
Traceback (most recent call last):
File "getpwuid_test.py", line 2, in <module>
print(getpwuid('0'))
TypeError: an integer is required
Run Code Online (Sandbox Code Playgroud)
这是因为在内部Modules/pwdmodule.c,getpwuid使用PyNumber_ParseTuple转换器PyNumber_Index来获取Python整数,并在失败时引发异常.
然而,在Modules/grpmodule.c,grp_getgrgid应用PyNumber_Long (或者PyNumber_Int一个老足够的Python)作为转换第一,并作为文件说,在https://docs.python.org/3/c-api/number.html,这是运行的等效int(o),可以将字符串转换为整数.只有这样才能PyNumber_Index通过辅助函数给予它_Py_Gid_Converter
造成这种差异的原因是什么?这是基于历史的故意选择吗?
这种行为getgrgid似乎更有帮助,奇怪的是它并不适用于这两种功能.在这种不良行为getgrgid或getpwuid?
有人可以解释CPython 2.7中字典的非单调内存使用吗?
>>> import sys
>>> sys.getsizeof({})
280
>>> sys.getsizeof({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5})
280
>>> sys.getsizeof({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6})
1048
>>> sys.getsizeof({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7})
1048
>>> sys.getsizeof({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'e
ight': 8})
664
>>> sys.getsizeof({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, …Run Code Online (Sandbox Code Playgroud) 我的一个python.exe(v3.5.2)进程挂起在远程Windows Server中.我无法从远程站点附加它,因此我创建了一个完整的内存转储并将其下载回分析.
但是,windbg在gdb中没有像py-bt这样的工具.我能做的是下载cpython符号文件并加载到windbg.
问题是: 如何打印python脚本调用堆栈就像"py-bt"一样?
调用堆栈如下所示,看起来像挂在HTTPS连接上
0:000> k
ChildEBP RetAddr
0050dd24 74592242 ntdll!ZwWaitForSingleObject+0xc
0050dd6c 7459bdee mswsock!SockWaitForSingleObject+0x143
0050ddf8 777561e0 mswsock!WSPRecv+0x391
0050de48 614d8e76 ws2_32!recv+0x103
0050de68 614138bb _ssl!sock_read+0x26 [c:\build\cpython\externals\openssl-1.0.2h\crypto\bio\bss_sock.c @ 141]
0050de90 614bc229 _ssl!BIO_read+0x5b [c:\build\cpython\externals\openssl-1.0.2h\crypto\bio\bio_lib.c @ 210]
0050debc 614bc36e _ssl!ssl3_read_n+0x1c9 [c:\build\cpython\externals\openssl-1.0.2h\ssl\s3_pkt.c @ 255]
0050df78 614bd136 _ssl!ssl3_get_record+0x9e [c:\build\cpython\externals\openssl-1.0.2h\ssl\s3_pkt.c @ 339]
0050dfb8 614c0bb5 _ssl!ssl3_read_bytes+0x1a6 [c:\build\cpython\externals\openssl-1.0.2h\ssl\s3_pkt.c @ 1228]
0050dfdc 614c0c13 _ssl!ssl3_read_internal+0x45 [c:\build\cpython\externals\openssl-1.0.2h\ssl\s3_lib.c @ 4459]
0050dfec 61402880 _ssl!ssl3_read+0x13 [c:\build\cpython\externals\openssl-1.0.2h\ssl\s3_lib.c @ 4483]
0050e034 613ff8f7 _ssl!_ssl__SSLSocket_read_impl+0x1f0 [c:\build\cpython\modules\_ssl.c @ 1944]
0050e080 61b12ae3 _ssl!_ssl__SSLSocket_read+0x67 [c:\build\cpython\modules\clinic\_ssl.c.h @ 267]
0050e09c 61b7409f python35!PyCFunction_Call+0x113 [c:\build\cpython\objects\methodobject.c …Run Code Online (Sandbox Code Playgroud) 我有一个dict像这样的子类:
class MyDict(dict):
def __getitem__(self, name):
return globals()[name]
Run Code Online (Sandbox Code Playgroud)
>>> eval('bytearray', MyDict())
<class 'bytearray'>
>>> exec('print(bytearray)', MyDict())
<class 'bytearray'>
Run Code Online (Sandbox Code Playgroud)
但是如果我用types.FunctionType构造函数实例化一个函数对象,该函数就无法访问任何内置函数:
import types
func = lambda: bytearray
func_copy = types.FunctionType(func.__code__,
MyDict(),
func.__name__,
func.__defaults__,
func.__closure__)
print(func_copy())
# Traceback (most recent call last):
# File "untitled.py", line 16, in <module>
# print(func_copy())
# File "untitled.py", line 8, in <lambda>
# func = lambda: bytearray
# NameError: name 'bytearray' is not defined
Run Code Online (Sandbox Code Playgroud)
替换MyDict()为globals() …
CPython 3.7 introduced the ability to step through individual opcodes in a debugger. However, I can't figure out how to read variables out of the bytecode stack.
For example, when debugging
def f(a, b, c):
return a * b + c
f(2, 3, 4)
Run Code Online (Sandbox Code Playgroud)
I want to find out that the inputs of the addition are 6 and 4. Note how 6 never touches locals().
So far I could only come up with the opcode information, but I don't …
我想知道在cpython中是否可以进行以下内省:
>>> def potato(x=69):
... if x == 69 and ???:
... print '69 was taken from argument defaults'
... if x == 69 and ???:
... print '69 was passed as positional arg'
... if x == 69 and ???:
... print '69 was passed as kwarg'
...
>>> potato()
69 was taken from argument defaults
>>> potato(69)
69 was passed as positional arg
>>> potato(x=69)
69 was passed as kwarg
Run Code Online (Sandbox Code Playgroud)
我对python2和python3的答案感兴趣,如果它们不同的话.
任何种类的Blackmagic涉及inspect,traceback,pdb, …
我想从 python 模块准备一个共享对象(.so)。我遇到了 Cython,它 a) 首先将 *.pyx 模块转换为 *.c 代码,b) 然后这个 *.c 代码将转换为共享对象 (.so)。Cython 的所有示例都说明了如何将这个 .so 导入到 python 中。
\n\n但是,我有兴趣从 C 代码中读取这个共享对象。当我编写示例 C 代码来读取 .so 时,它会抛出一个错误,指出 .pyx 中实际存在的方法并不存在于 .so 对象中。
\n\n我想知道 \na) 是否可以从不同的语言(例如 C)读取 Cython 的共享对象 \nb) 而且,如果上述语句为 True,我必须在代码中进行哪些更改,以便我将能够从 C 读取共享对象。
\n\n谢谢,
\n\nPython代码(保存为square_number.pyx)
\n\ndef square_me(int x):\n return x * x\nRun Code Online (Sandbox Code Playgroud)\n\nCython 对应的 setup.py 文件
\n\nfrom distutils.core import setup\nfrom Cython.Build import cythonize\n\nsetup(\n ext_modules=cythonize("square_number.pyx"),\n )\nRun Code Online (Sandbox Code Playgroud)\n\n将上述 .pyx 转换为 .So 的命令行语句(通过 cython)
\n\npython setup.py …Run Code Online (Sandbox Code Playgroud) cpython ×10
python ×10
debugging ×2
python-2.7 ×2
python-2.x ×2
c ×1
closures ×1
dictionary ×1
function ×1
global ×1
memory ×1
pdb ×1
python-3.x ×1
reference ×1
string ×1
windbg ×1