标签: cpython

`list in list`的行为与`dict中的`不同?

我有一个带有一些对象的迭代器,我想创建一个uniqueUsers的集合,其中我只列出每个用户一次.所以玩了一下我用列表和字典尝试了它:

>>> for m in ms: print m.to_user  # let's first look what's inside ms
...
Pete Kramer
Pete Kramer
Pete Kramer
>>> 
>>> uniqueUsers = []  # Create an empty list
>>> for m in ms:
...     if m.to_user not in uniqueUsers:
...         uniqueUsers.append(m.to_user)
...
>>> uniqueUsers
[Pete Kramer]  # This is what I would expect
>>> 
>>> uniqueUsers = {}  # Now let's create a dict
>>> for m in ms:
...     if m.to_user not in uniqueUsers:
... …
Run Code Online (Sandbox Code Playgroud)

python dictionary if-statement cpython list

12
推荐指数
2
解决办法
450
查看次数

如果元组在设计上是不可变的,为什么 cpython 将“PyTuple_SetItem”公开为 C-API?

中的元组在设计上是不可变的,因此如果我们尝试改变元组对象,会发出以下TypeError有意义的信息。

>>> a = (1, 2, 3)
>>> a[0] = 12
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,如果元组在设计上是不可变的,为什么cpython 公开PyTuple_SetItem为 C-API

从文档中它被描述为

int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)

o在 指向的元组的 pos 位置插入对对象的引用p0成功归来。如果 pos 越界,则返回-1并设置 IndexError 异常。

这句话不是和tuple[index] = valuepython层中的完全一样吗?如果目标是从项目集合创建一个元组,我们可以使用PyTuple_Pack.

附加说明:

经过大量的试验和错误后,ctypes.pythonapi我设法使用以下命令来改变元组对象PyTuple_SetItem

import ctypes

from …
Run Code Online (Sandbox Code Playgroud)

python ctypes tuples cpython python-3.x

12
推荐指数
1
解决办法
733
查看次数

切片`a`(例如`a [1:] == a [: - 1]`)是否创建了`a`的副本?

我的一个朋友向我展示了以下Python代码:

a[1:] == a[:-1]
Run Code Online (Sandbox Code Playgroud)

如果所有项目a都相同,则返回True .

我认为代码很难从一见钟情中理解,而且 - 它在内存使用方面效率低下,因为a将为比较创建两个副本.

我用Python dis来看看幕后发生了什么a[1:]==a[:-1]:

>>> def stanga_compare(a):
...     return a[1:]==a[:-1]
...
>>> a=range(10)
>>> stanga_compare(a)
False
>>> a=[0 for i in range(10)]
>>> stanga_compare(a)
True

>>> dis.dis(stanga_compare)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_CONST               1 (1)
              6 SLICE+1
              7 LOAD_FAST                0 (a)
             10 LOAD_CONST               2 (-1)
             13 SLICE+2
             14 COMPARE_OP               2 (==)
             17 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

归结为两个切片命令 - SLICE+1SLICE+2.文档不清楚这些操作码是否实际创建了一个新副本a,或仅仅是对它的引用.

  • SLICE命令是否复制a …

python cpython memory-efficient python-internals

11
推荐指数
1
解决办法
320
查看次数

Python hasattr vs getattr

我最近一直在阅读一些关于hasattr的推文python文档,它说:

hasattr(对象,名称)

参数是一个对象和一个字符串.如果字符串是>>对象属性之一的名称,则结果为True,否则返回False.(这是通过调用getattr(object,name)并查看它是否引发AttributeError来实现的.)

Python中有一句座右铭,就是我通常同意的许可更容易要求宽恕.

在这种情况下,我尝试使用一个非常简单的python代码进行性能测试:

import timeit
definition="""\
class A(object):
    a = 1
a = A()
"""

stm="""\
hasattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)

stm="""\
getattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)
Run Code Online (Sandbox Code Playgroud)

结果如下:

$ python test.py
hasattr(a, 'a')
1.26515984535

getattr(a, 'a')
1.32518696785
Run Code Online (Sandbox Code Playgroud)

如果属性不存在且getattr和hasattr之间的差异更大,我也尝试了会发生什么.所以我到目前为止看到的是getattr比hasattr慢,但在文档中它说它调用了getattr.

我搜索了hasattrgetattr的CPython实现,似乎都调用了下一个函数:

v = PyObject_GetAttr(v, name);
Run Code Online (Sandbox Code Playgroud)

但是getattr中的样板比hasattr中的样板更多,这可能使它更慢.

有谁知道为什么在文档中我们说hasattr调用getattr并且我们似乎鼓励用户使用getattr而不是hasattr,当它真的不是由于性能?只是因为它更pythonic?

也许我在测试中做错了什么:)

谢谢,

劳尔

python cpython python-2.7 python-3.x

11
推荐指数
1
解决办法
2万
查看次数

如何在内部存储和映射变量名称?

我阅读/sf/answers/1380476751/,似乎在CPython中,变量只是与引用相关联的名称.

声明x = 5有几件事情:

  1. 创建一个值为5的int对象(如果已存在,则找到该对象)
  2. 创建名称x(或与最后一个标记为'x'的对象取消关联)
  3. 对新(或找到)的int对象的引用计数增加1
  4. 名称x与创建(或找到)值为"5"的对象相关联.

但是,我仍然不清楚内部如何实现变量.

即:

  1. 创建名称x(或与最后一个标记为'x'的对象取消关联);

那个名字也不会占用内存空间吗?sys.sizeof(x)等于sys.sizeof(5),我得到的sys.sizeof(x)只能返回相关引用的大小,但那么名称的大小是x多少?

  1. 名称x与创建(或找到)值为'5'的对象相关联

这是如何在内部实施的?我认为在高级别它可以用a完成dict,其中键是变量名(str?),值是与之关联的引用.

python variables cpython python-internals

11
推荐指数
1
解决办法
2079
查看次数

ValueError:使用conda命令后无法解析CPython sys.version

我遇到了一个我无法解决的错误,尽管其他人报告了同样的错误.

我正在远程连接到Linux机器.我安装了最新版的anaconda:

$ bash Anaconda2-2.4.0-Linux-x86_64.sh

// A lot of python libraries get installed

installing: _cache-0.0-py27_x0 ...
Python 2.7.10 :: Continuum Analytics, Inc.
creating default environment...
installation finished. 
Run Code Online (Sandbox Code Playgroud)

我更新了相应的路径,它似乎工作:

$ python
Python 2.7.10 |Anaconda 2.4.0 (64-bit)| (default, Oct 19 2015, 18:04:42) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
Run Code Online (Sandbox Code Playgroud)

很好,所以现在我想使用conda,预装Anaconda.看起来Anaconda给了我3.18.3:

$ conda --version
conda 3.18.3
Run Code Online (Sandbox Code Playgroud)

按照 …

python cpython anaconda conda

11
推荐指数
2
解决办法
1万
查看次数

cpython的字符串实习有哪些规则?

在python 3.5中,是否可以预测何时获得实习字符串或何时获得副本?在阅读了有关此问题的一些Stack Overflow答案后,我发现这个答案最有帮助但仍然不全面.比我查看Python文档,但默认情况下不保证实习

通常,Python程序中使用的名称会自动实现,而用于保存模块,类或实例属性的字典具有实习键.

所以,我的问题是关于内部intern()条件,即决策(是否实习生字符串字面与否):为什么同样的代码工作在一个系统上,而不是在一个又一个,什么规则做了回答笔者就提到的话题平均值说的时候

何时发生这种情况的规则相当复杂

string cpython string-interning

11
推荐指数
1
解决办法
205
查看次数

使用ctypes检索本机基类的地址

我希望能够将证书传递给Python的ssl库,而无需临时文件.似乎Python的ssl模块不能这样做.

要解决此问题,我想从本机模块中检索SSL_CTX存储在ssl._ssl._SSLContext类中的基础结构_ssl.使用ctypes然后我可以SSL_CTX_*使用该上下文从libssl 手动调用相应的函数.这里显示如何在C中执行此操作,我将通过ctypes执行相同的操作.

不幸的是,我陷入了我设法挂钩load_verify_locations函数的地步,ssl._ssl._SSLContext但似乎无法获得ssl._ssl._SSLContext结构实例的正确内存地址.load_verify_locations看到的所有函数都是父ssl.SSLContext对象.

我的问题是,如何从ssl.SSLContext对象的实例到本机基类的内存ssl._ssl._SSLContext?如果我愿意,我可以轻松访问其ctx成员.

到目前为止,这是我的代码.关于如何将本机Python模块进行monkeypatch的信用转到Lincoln Clarete的禁果项目

Py_ssize_t = hasattr(ctypes.pythonapi, 'Py_InitModule4_64') and ctypes.c_int64 or ctypes.c_int

class PyObject(ctypes.Structure):
    pass

PyObject._fields_ = [
    ('ob_refcnt', Py_ssize_t),
    ('ob_type', ctypes.POINTER(PyObject)),
]

class SlotsProxy(PyObject):
    _fields_ = [('dict', ctypes.POINTER(PyObject))]

class PySSLContext(ctypes.Structure):
    pass

PySSLContext._fields_ = [
        ('ob_refcnt', Py_ssize_t),
        ('ob_type', ctypes.POINTER(PySSLContext)),
        ('ctx', ctypes.c_void_p),
        ]

name = …
Run Code Online (Sandbox Code Playgroud)

ctypes monkeypatching cpython pyopenssl python-3.x

11
推荐指数
1
解决办法
327
查看次数

使用 pyo3 从 rust 移植到 python 的类的 __str__ 函数未用于打印

我正在使用pyo3rust crate (version 0.11.1) 以便将 rust 代码移植到 cpython (version 3.8.2) 代码中。我创建了一个名为类my_class,定义了以下功能:new__str__,和__repr__

TL;DR:该__str__函数存在于使用 pyo3 crate 从 rust 移植的类上,但在使用时不会打印print(obj),而是必须编写print(obj.__str__())

my_class定义是在这里:

use pyo3::prelude::*;

#[pyclass]
struct my_class {
    #[pyo3(get, set)]
    num: i32,
    #[pyo3(get, set)]
    debug: bool,
}

#[pymethods]
impl my_class {
    #[new]
    fn new(num: i32, debug: bool) -> Self {
        my_class {num, debug}
    }
    fn __str__(&self) -> PyResult<String>   {
        Ok(format!("[__str__] Num: {}, Debug: {}", …
Run Code Online (Sandbox Code Playgroud)

python cpython object rust

11
推荐指数
1
解决办法
456
查看次数

为 python 模块创建 golang 绑定

我想为现有的(第三方)Python 模块编写 golang 绑定。目的是想使用Golang中Python模块提供的API。

我已经找到了 Python 的 C API 的 golang 绑定(py3 的go-python3和 py2 的go-python),但我仍然没有弄清楚如何将相对复杂的 Python 模块转换为 Golang(即如何处理类型安全在python中寻找不安全的输入和返回等)。

什么是好的方法?该领域是否有任何预先存在的工具?有没有关于 Python 代码的 Golang 绑定的好例子?(我找不到很多 tbh)。

python binding cpython go

10
推荐指数
1
解决办法
3075
查看次数