如何PyObject从C++ 获取a的引用计数?
有功能Py_INCREF,Py_DECREF并增加/减少它,但我没有找到任何返回对象的引用计数的函数.
我需要它用于调试目的.
为什么str(list)返回我们在控制台上看到列表的方式?str(list)工作怎么样?(对CPython代码的任何引用str(list))?
>>> x = ['abc', 'def', 'ghi']
>>> str(x)
"['abc', 'def', 'ghi']"
Run Code Online (Sandbox Code Playgroud)
要获得原始列表,str(list)我必须:
>>> from ast import literal_eval
>>> x = ['abc', 'def', 'ghi']
>>> str(x)
"['abc', 'def', 'ghi']"
>>> list(str(x))
['[', "'", 'a', 'b', 'c', "'", ',', ' ', "'", 'd', 'e', 'f', "'", ',', ' ', "'", 'g', 'h', 'i', "'", ']']
>>> literal_eval(str(x))
['abc', 'def', 'ghi']
Run Code Online (Sandbox Code Playgroud)
为什么不list(str(list))转动str(list)回原来的名单?
或者我可以使用:
>>> eval(str(x))
['abc', 'def', 'ghi']
Run Code Online (Sandbox Code Playgroud)
是literal_eval …
我正在阅读一些基本上看起来像这样的代码:
class Foo(object):
class_name = __module__.replace('_', '-')
Run Code Online (Sandbox Code Playgroud)
对我来说,这看起来很奇怪(__module__那是什么?)所以我去了看python 数据模型.快速搜索显示这__module__是类对象和函数对象的属性.但是,__module__全局命名空间中没有可用的东西(只需要通过查看它并观察NameError结果就可以轻松验证...).
我决定将其用于实现特定的行为,但作为最后的检查,我决定使用其他实现进行测试.事实证明,此代码以1执行
我的问题是这种行为是否实际上是在语言参考中的任何地方定义的.我不确定我为什么__module__要这样做,但是我可以安全地依赖于类创建命名空间,还是所有实现者都决定以同样的方式执行此操作?
1所有linux,但我怀疑这很重要......
为什么OrderedDict键视图比较顺序不敏感?
>>> from collections import OrderedDict
>>> xy = OrderedDict([('x', None), ('y', None)])
>>> yx = OrderedDict([('y', None), ('x', None)])
>>> xy == yx
False
>>> xy.keys() == yx.keys()
True
Run Code Online (Sandbox Code Playgroud)
OrderedDict键视图应该表现得像OrderedSet,但它的行为相同dict.keys(就像通常一样set).
python2中的"问题"相同:
>>> xy.viewkeys() == yx.viewkeys()
True
Run Code Online (Sandbox Code Playgroud)
它们是不同的类型,(odict_keys是子类dict_keys)
>>> type(xy.keys())
odict_keys
>>> type({}.keys())
dict_keys
Run Code Online (Sandbox Code Playgroud)
并且已经存在一个可以轻易使用的顺序敏感键比较,但它显然仅用作对odict丰富比较的后检查.
这是设计决定还是错误?如果这是一个设计决定,我在哪里可以找到理由的讨论?
在__init__.py运行文件时,导入时的行为似乎与导入时的行为不同.
如果我们有以下文件:
run.py:
import test
Run Code Online (Sandbox Code Playgroud)
test/b.py:
class B(object):
pass
Run Code Online (Sandbox Code Playgroud)
test/__init__.py:
from b import B
print B
print b
Run Code Online (Sandbox Code Playgroud)
如果我们运行,__init__.py我们会得到一个错误:
% python test/__init__.py
<class 'b.B'>
Traceback (most recent call last):
File "test/__init__.py", line 6, in <module>
print b
NameError: name 'b' is not defined
Run Code Online (Sandbox Code Playgroud)
但如果我们run.py这样做,那么我们不会:
% python run.py
<class 'test.b.B'>
<module 'test.b' from '~/temp/test/b.py'>
Run Code Online (Sandbox Code Playgroud)
我希望这种行为是一样的.为什么这样做?
这只有在我们这样做的情况下才有效__init__.py.要是我们:
mv __init__.py a.py
touch __init__.py
Run Code Online (Sandbox Code Playgroud)
并使run.py:
import test.a
Run Code Online (Sandbox Code Playgroud)
然后我们得到了错误.
我找到了一些有趣的东西,这里有一段代码:
class A(object):
def __init__(self):
print "A init"
def __del__(self):
print "A del"
class B(object):
a = A()
Run Code Online (Sandbox Code Playgroud)
如果我运行此代码,我会得到:
A init
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改class B(object)到class B(),我会得到:
A init
A del
Run Code Online (Sandbox Code Playgroud)
我在__del__ doc中找到了一个注释:
无法保证为解释器退出时仍然存在的对象调用del()方法.
然后,我想这是因为当解释器存在时B.a仍然引用(由类引用B).
所以,我del B在解释器手动存在之前添加了一个,然后我发现它a.__del__()被调用了.
现在,我对此感到有些困惑.为什么a.__del__()在使用旧样式时调用?为什么新旧风格的行为有不同的行为?
我在这里发现了类似的问题,但我认为答案还不够明确.
我阅读/sf/answers/1380476751/,似乎在CPython中,变量只是与引用相关联的名称.
声明x = 5有几件事情:
- 创建一个值为5的int对象(如果已存在,则找到该对象)
- 创建名称x(或与最后一个标记为'x'的对象取消关联)
- 对新(或找到)的int对象的引用计数增加1
- 名称x与创建(或找到)值为"5"的对象相关联.
但是,我仍然不清楚内部如何实现变量.
即:
- 创建名称x(或与最后一个标记为'x'的对象取消关联);
那个名字也不会占用内存空间吗?sys.sizeof(x)等于sys.sizeof(5),我得到的sys.sizeof(x)只能返回相关引用的大小,但那么名称的大小是x多少?
- 名称x与创建(或找到)值为'5'的对象相关联
这是如何在内部实施的?我认为在高级别它可以用a完成dict,其中键是变量名(str?),值是与之关联的引用.
python随机模块的性能问题,特别是,random.sample并random.shuffle提出了这个问题.在我的计算机上,我得到以下结果:
> python -m timeit -s 'import random' 'random.randint(0,1000)'
1000000 loops, best of 3: 1.07 usec per loop
> python3 -m timeit -s 'import random' 'random.randint(0,1000)'
1000000 loops, best of 3: 1.3 usec per loop
Run Code Online (Sandbox Code Playgroud)
在python3和python2中,性能下降超过20%.它变得更糟.
> python -m timeit -s 'import random' 'random.shuffle(list(range(10)))'
100000 loops, best of 3: 3.85 usec per loop
> python3 -m timeit -s 'import random' 'random.shuffle(list(range(10)))'
100000 loops, best of 3: 8.04 usec per loop
> python -m timeit …Run Code Online (Sandbox Code Playgroud) 码:
from weakref import WeakSet
se = WeakSet()
se.add(1)
Run Code Online (Sandbox Code Playgroud)
输出:
TypeError: cannot create weak reference to 'int' object
Run Code Online (Sandbox Code Playgroud)
Doc:
一些内置类型(如list和dict)不直接支持弱引用,但可以通过子类化添加支持:
...
其他内置类型(如tuple和int)即使在子类化时也不支持弱引用(这是一个实现细节,并且可能在各种Python实现中有所不同).
这表达不足以解释:
为什么有些内置类型不支持弱引用?
那些支持弱引用的类型究竟是什么?
添加一些想法:
对于上面的例子,你可以一个用户定义的包装类内包装的INT,而包装类支持弱引用(那些谁是熟悉Java会记得int和Integer):
from weakref import WeakSet
se = WeakSet()
class Integer:
def __init__(self, n=0):
self.n = n
i = 1
I = Integer(1)
se.add(i) # fail
se.add(I) # ok
Run Code Online (Sandbox Code Playgroud)
我不知道为什么Python不常用的内置类型(提供自动换行int,str等等),而是简单地说,他们不支持弱引用.这可能是由于性能问题,但不能弱化这些内置类型大大减少了它的使用.
根据object.__eq__()文档,默认(即在object类中)实现==如下:
True if x is y else NotImplemented
Run Code Online (Sandbox Code Playgroud)
仍然遵循的文档NotImplemented,我推断这NotImplemented意味着 Python 运行时将尝试以相反的方式进行比较。y.__eq__(x)即如果x.__eq__(y)返回则尝试NotImplemented(在运算符的情况下==)。
现在,在 python 3.9 中False打印以下代码:True
class A:
pass
print(A() == A())
print(bool(NotImplemented))
Run Code Online (Sandbox Code Playgroud)
所以我的问题如下:文档在哪里提到了NotImplemented在上下文中的特殊行为__eq__?
PS:我在CPython 源代码中找到了答案,但我想这必须/应该在文档中的某个位置。
python ×10
python-internals ×10
python-3.x ×3
c ×1
c++ ×1
cpython ×1
eval ×1
list ×1
optimization ×1
python-2.7 ×1
python-2.x ×1
python-c-api ×1
random ×1
string ×1
variables ×1