小编tho*_*len的帖子

顶级 __init__.py 导入的最佳实践

当包变得很大时,可能很难记住东西在哪里,并且我们想要的对象的点路径可能很麻烦。作者似乎解决这个问题的一种方法是将“最好的”对象的引用带到顶部,尽管这些代码实际上可以存在于下面的几个包级别中。

这让人可以说:

from pandas import wide_to_long
Run Code Online (Sandbox Code Playgroud)

代替

from pandas.core.reshape.melt import wide_to_long
Run Code Online (Sandbox Code Playgroud)

但是这样做的来龙去脉以及该方法的最佳实践是什么?不加载__init__.py带有许多导入的顶部(为了使它们在顶层可用)是否意味着包的单个对象的任何导入突然会占用比所需更多的内存 - 因为 中提到的所有内容都会自动__init__.py加载?

然而,包却可以做到这一点。例如,看看可以从顶层numpy或底层导入什么(可以在这个要点pandas中找到运行您自己的诊断的代码)。

$ python print_top_level_diagnosis.py numpy
--------- numpy ---------
599 objects can be imported from top level numpy:
  19 modules
  300 functions
  104 types

depth   count
0   162
1   406
2   2
3   29
4   1

$ python print_top_level_diagnosis.py pandas
--------- pandas ---------
115 objects can be imported from top level pandas:
  12 modules
  55 functions
  40 …
Run Code Online (Sandbox Code Playgroud)

python python-import python-3.x

15
推荐指数
1
解决办法
3434
查看次数

如何查看github组织的所有问题

该 GitHub 组织(到目前为止)拥有 27 个存储库。我希望能够立即查看所有这些内容,而不必逐一前往每个单独的存储库来查看其问题。

github github-issues

7
推荐指数
1
解决办法
2157
查看次数

为什么解包非标识符字符串可以在函数调用中起作用?

令我惊讶的是,我注意到在函数调用中,我可以用甚至不是有效的 python 标识符的dict字符串来解压 a 。

让我感到惊讶的是,因为参数名称必须是标识符,因此允许函数调用解包**kwargs具有非标识符的 a 且没有运行时错误,这似乎并不健康(因为它可能会将问题埋藏得比实际发生的地方更深)。

除非能够做到这一点有实际用途,在这种情况下我的问题就变成“那会有什么用途?”。

示例代码

考虑这个函数:

def foo(**kwargs):
    first_key, first_val = next(iter(kwargs.items()))
    print(f"{first_key=}, {first_val=}")
    return kwargs
Run Code Online (Sandbox Code Playgroud)

这表明,在函数调用中,您无法解压dict具有整数键的 a,这是预期的。

>>> t = foo(**{1: 2, 3: 4})
TypeError                                 Traceback (most recent call last)
...
TypeError: foo() keywords must be strings
Run Code Online (Sandbox Code Playgroud)

另一方面,真正出乎意料且令人惊讶的是,您可以使用dict字符串键解压 a,即使这些不是有效的 python 标识符:

>>> t = foo(**{'not an identifier': 1, '12': 12, ',(*&$)': 100})
first_key='not an identifier', first_val=1
>>> t
{'not an identifier': 1, '12': 12, …
Run Code Online (Sandbox Code Playgroud)

python python-3.x

7
推荐指数
1
解决办法
346
查看次数

如何使用带有字节而不是文件的python子进程

我可以ffmpeg通过这样做将 mp4 转换为 wav,使用,:

ffmpeg -vn test.wav  -i test.mp4 
Run Code Online (Sandbox Code Playgroud)

subprocess只要我的输入和输出是文件路径,我也可以使用它来做同样的事情。

但是如果我想ffmpeg直接在字节或“类文件”对象上使用io.BytesIO()怎么办?

这是一个尝试:

ffmpeg -vn test.wav  -i test.mp4 
Run Code Online (Sandbox Code Playgroud)

给我:

---------------------------------------------------------------------------
UnsupportedOperation                      Traceback (most recent call last)
<ipython-input-84-0ddce839ebc9> in <module>
      5 with open('test.mp4', 'rb') as stream:
      6     command = ['ffmpeg', '-i']
----> 7     proc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=b)
...
   1486                 # Assuming file-like object
-> 1487                 c2pwrite = stdout.fileno()
   1488 
   1489             if stderr is None:

UnsupportedOperation: fileno
Run Code Online (Sandbox Code Playgroud)

当然,我可以使用临时文件来收集我的字节,但我希望能够避免写入磁盘(因为这一步只是转换管道中的一个链接)。

python subprocess ffmpeg

6
推荐指数
1
解决办法
2343
查看次数

动态获取标准库python包名称列表

我想获得所有标准库包的名称列表。

通过这种方式,我的意思是那些我认为上市解析https://docs.python.org/3/library/:字符串name为其

__import__(name)
Run Code Online (Sandbox Code Playgroud)

sys.builtin_module_names 看起来很有希望,但事实并非如此。

我想过解析~/.pyenv/versions/3.8.6/lib/python3.8/或https://docs.python.org/3/library/,但肯定有更好的方法!

附录

对于那些需要X 代表 Y 的人:我正在静态导航包的导入以分析它们——即,查看使用了哪些第三方包、哪些标准库、使用频率等。

python python-import

6
推荐指数
1
解决办法
138
查看次数

如何在用户 github 帐户的所有存储库中使用机密?

在“组织”github帐户中,我可以设置一些全局秘密,PYPI_USERNAME并使PYPI_PASSWORD它们“可用于公共存储库”,然后在我的中使用它们,ci.yml如下所示:

twine upload dist/$PROJECT_NAME-$VERSION.tar.gz -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} --non-interactive  --skip-existing --disable-progress-bar
Run Code Online (Sandbox Code Playgroud)

但在我的“用户”github 帐户中,我找不到任何此类组织范围内的秘密,因此我发现自己必须为每个单独的存储库输入我的秘密,这是反人类罪(现在)。

github-actions

6
推荐指数
1
解决办法
2991
查看次数

“functools.partial”行为的基本原理

functools.partial我想知道这些和事实背后的故事 - 无论是声音设计还是继承的遗产 - inspect.signature(这里谈论 python 3.8)。

设置:

from functools import partial
from inspect import signature

def bar(a, b):
    return a / b
Run Code Online (Sandbox Code Playgroud)

一切都从以下开始,这似乎符合咖喱标准。我们正在固定a位置3,a从签名中消失,它的值确实绑定到3:

f = partial(bar, 3)
assert str(signature(f)) == '(b)'
assert f(6) == 0.5 == f(b=6)
Run Code Online (Sandbox Code Playgroud)

如果我们尝试为 指定一个替代值a,f不会告诉我们我们得到了一个意外的关键字,而是告诉我们它有多个参数值a:

f = partial(bar, 3)
assert str(signature(f)) == '(b)'
assert f(6) == 0.5 == f(b=6)
Run Code Online (Sandbox Code Playgroud)

但现在如果我们b=3通过关键字修复,b则不会从签名中删除,它是对仅关键字的更改,我们仍然可以使用它(覆盖默认值,作为正常的默认值,这是我们在a之前无法做到的)案件):

f(a=2, …
Run Code Online (Sandbox Code Playgroud)

python functools

6
推荐指数
1
解决办法
1267
查看次数

修改Python函数的签名和默认值,hack-way

我试图更好地理解 python 数据模型,但遇到了一些奇怪的事情。

def foo(a, b = 2):
    return a / b

assert foo(20) == 10.0

# note: for sanity purposes, should also change signature, but not needed for effect
foo.__defaults__ = (10,)
assert foo(20) == 2.0

foo.__defaults__ = ()
foo.__kwdefaults__ = {'b': 10}

foo(20)  # raises TypeError: foo() missing 1 required positional argument: 'b'
Run Code Online (Sandbox Code Playgroud)

预计会出现错误:__kwdefaults__仅针对关键字参数,因此让我们创建b一个仅关键字参数来尝试解决此问题:

from inspect import signature

foo.__signature__ = signature(lambda a, *, b=10: None)
foo(20)  # still raises TypeError: foo() missing 1 required …
Run Code Online (Sandbox Code Playgroud)

python

6
推荐指数
1
解决办法
1999
查看次数

用于转换函数或方法的输入和/或输出的 Python 装饰器

下面的函数确实(似乎)完成了这项工作,但似乎有比必要的更多的样板。

我确信有一种更优雅的方法。它将部分代码分解出来,使其看起来不像现在的复制/粘贴/编辑补丁工作。

但请注意,优雅并不是一切:我不希望性能受到影响。例如,我可以通过执行两个装饰器将代码减半:一个用于输入转换,另一个用于输出转换。但这会比当前版本效率低。

def input_output_decorator(preprocess=None, postprocess=None):
    def decorator(func):
        if inspect.ismethod(func):
            if preprocess is not None:
                if postprocess is not None:  # both pre and post processes
                    @wraps(func)
                    def func_wrapper(self, *args, **kwargs):
                        return postprocess(func(self, preprocess(*args, **kwargs)))
                else:  # a preprocess but no postprocess
                    @wraps(func)
                    def func_wrapper(self, *args, **kwargs):
                        return func(self, preprocess(*args, **kwargs))
            else:  # no preprocess
                if postprocess is not None:  # no preprocess, but a postprocess
                    @wraps(func)
                    def func_wrapper(self, *args, **kwargs):
                        return postprocess(func(*args, **kwargs))
                else:  # no pre or post …
Run Code Online (Sandbox Code Playgroud)

python python-decorators

5
推荐指数
2
解决办法
3631
查看次数

知道 python 缓存的属性是否已被访问而无需实际访问它

有许多方法装饰器的示例可以将方法转换为缓存的属性。但有时,我想检查缓存是否处于“活动”状态,这意味着该属性已被访问并且缓存已被填充。

例如,如果我使用rows缓存将 sql 表存储在 a 中rows,我想根据缓存计算表的长度(如果已填充),但如果没有填充,则通过单独的 sql 调用。如何在rows不触发访问的情况下检查是否已被访问?

这是一个很好的装饰器,取自 David Beazley 的“Python Cookbook”),我正在使用它来满足我的缓存属性需求。我已经增强了它以启用我当前的黑客。

class lazyprop:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, cls):
        if instance is None:
            return self
        else:
            value = self.func(instance)
            setattr(instance, self.func.__name__, value)
            setattr(instance, self.func.__name__ + '__cache_active', True)  # my hack
            return value
Run Code Online (Sandbox Code Playgroud)

使用示例:

>>> class Test:
...     def __init__(self, a):
...         self.a = a
...     @lazyprop
...     def len(self):
...         print('generating "len"')
...         return len(self.a)
>>> t = …
Run Code Online (Sandbox Code Playgroud)

python python-descriptors

5
推荐指数
1
解决办法
2206
查看次数

Python 的新 `functools.cached_property` 错误或限制?

从 Python 3.8 开始,functools有一个cached_property. 我一直在使用lazyprop基于 Beazley 的食谱(下面的代码)的类似装饰器,但是当我用内置函数替换时,我遇到了问题。这是其中之一。

当我在类定义中使用装饰器时,使用@运算符,它不会抱怨。

但是如果我将它与 一起使用setattr,我会得到:

TypeError: Cannot use cached_property instance without calling __set_name__ on it.
Run Code Online (Sandbox Code Playgroud)

Beazley 的简单版本虽然很好用。

TypeError: Cannot use cached_property instance without calling __set_name__ on it.
Run Code Online (Sandbox Code Playgroud)

python python-3.x

5
推荐指数
1
解决办法
1609
查看次数

是否可以在使用时而不是在文件顶部导入依赖项?

假设我有一个包含一堆对象的模块,其中没有一个需要第三方库。好吧,几乎没有:一个函数(称为 )asterix()需要第三方包。asterix()不是该模块的重点,但在需要时使用很方便。

仅仅为了这个功能就必须要求并导入整个第三方包似乎是一种耻辱。我有什么选择?转移asterix()到另一个模块/包或供应商似乎很愚蠢。

我发现快速和干净的最佳平衡是简单地在asterix()其内部进行导入,可能需要一些额外的 try/ except 逻辑。它违反了最小意外原则和进口优先的惯例。但我告诉自己我永远都会违反一些事情。

群众智慧对此有何看法?我缺少什么明显的东西吗?

def asterix(...):
    try:
        import something_special
    except ModuleNotFoundError as err:
        # do something about err (help the user out!)
    # The special code...
Run Code Online (Sandbox Code Playgroud)

python

5
推荐指数
1
解决办法
365
查看次数