小编wks*_*rtz的帖子

Python 3:在多处理过程中捕获警告

太长; 没看过

warnings.catch_warnings()上下文管理是不是线程安全的.如何在并行处理环境中使用它?

背景

下面的代码使用Python multiprocessing模块的并行处理解决了最大化问题.它需要一个(不可变的)小部件列表,将它们分区(参见Python 3中大规模,强力最大化的高效多处理),找到所有分区的最大值("最终者"),然后找到最大值("冠军")那些"入围者".如果我正确地理解了我自己的代码(如果我这样做,我就不会在这里),我正在与所有子进程共享内存以给它们输入小部件,并multiprocessing使用操作系统级管道和pickle来发送当工人完成时,决赛小工具回到主要过程.

问题的根源

我希望捕获在窗口小部件从进程间管道出来时发生的取消对象之后由窗口小部件重新实例化引起的冗余窗口小部件警告.当窗口小部件对象实例化时,它们会验证自己的数据,从Python标准warnings模块发出警告,告诉应用程序的用户该窗口小部件怀疑用户的输入数据存在问题.因为unpickling导致对象实例化,所以我对代码的理解意味着每个widget对象只重新实例化一次,当且仅当它从管道出来后才是决赛者 - 请参阅下一节以了解为什么这不正确.

这些小部件在被擦除之前就已经创建了,因此用户已经痛苦地意识到他输入了什么输入并且不想再听到它.这些是我想要通过warnings模块的catch_warnings()上下文管理器捕获的警告(即with声明).

解决方案失败

在我的测试中,当多余的警告被发射到我在下面标记为A 线B 线之间的任何地方时,我已经缩小了范围.让我感到惊讶的是,警告是在不仅仅是附近的地方发出的output_queue.get().这意味着我multiprocessing使用酸洗将小部件发送给工人.

结果是,warnings.catch_warnings()即使在从A行B 行的所有内容中创建上下文管理器,并在此上下文中设置正确的警告过滤器也不会捕获警告.这意味着警告正在工作进程中发出.将此上下文管理器放在工作器代码周围也不会捕获警告.

代码

这个例子省略了决定,如果问题的规模太小,与派生工艺,进口多,并确定打扰的代码my_frobnal_counter,和my_load_balancer.

"Call `frobnicate(list_of_widgets)` to get the widget with the most frobnals"

def frobnicate_parallel_worker(widgets, output_queue):
    resultant_widget = max(widgets, key=my_frobnal_counter)
    output_queue.put(resultant_widget)

def frobnicate_parallel(widgets):
    output_queue = …
Run Code Online (Sandbox Code Playgroud)

python warnings multiprocessing python-3.x

34
推荐指数
1
解决办法
1599
查看次数

在Python中收集和报告多个异常的惯用方法

人们过去常常在Python中捕获,记录和报告多个数据验证错误?

我正在Python 3中构建一个应用程序,它首先验证输入数据然后处理它.第一步报告错误是程序预期功能的一部分,因此我不希望我的验证器放弃第一个异常.特别是,数据是表格式的,我希望能够返回 - 而不是引发 - 表格的每一行都没有验证.

几年前的一次论坛讨论考虑了多种解决方案,包括以下内容,这对我来说似乎是最干净的:

errors = []
for item in data:
    try:
        process(item)
    except ValidationError as e:
        errors.append(e)
if errors:
    raise MultipleValidationErrors(errors)
Run Code Online (Sandbox Code Playgroud)

其中MultipleValidationErrors类需要有一个适当的__str__方法来列出所有有用的信息ValidationErrors在里面.

其他人建议使用该traceback模块,但由于我想要捕获的异常是数据验证错误而不是程序错误,这似乎是不合适的.但是,获取所logging涉及的模块可能是合适的.

python logging exception

29
推荐指数
1
解决办法
5053
查看次数

Python:multiprocessing.map:如果一个进程引发异常,为什么不调用其他进程的finally块?

我的理解是,如果输入了try,则必须*始终*执行finally子句.

import random

from multiprocessing import Pool
from time import sleep

def Process(x):
  try:
    print x
    sleep(random.random())
    raise Exception('Exception: ' + x)
  finally:
    print 'Finally: ' + x

Pool(3).map(Process, ['1','2','3'])
Run Code Online (Sandbox Code Playgroud)

预期的输出是对于每个由第8行单独打印的x,必须出现'Finally x'.

示例输出:

$ python bug.py 
1
2
3
Finally: 2
Traceback (most recent call last):
  File "bug.py", line 14, in <module>
    Pool(3).map(Process, ['1','2','3'])
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 225, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 522, in get
    raise self._value
Exception: Exception: 2
Run Code Online (Sandbox Code Playgroud)

似乎终止一个进程的异常终止了父进程和兄弟进程,即使在其他进程中还有其他工作 …

python multithreading multiprocessing try-catch-finally

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

在Python中散列不可变字典

简短版本:作为无序项目字典实现的多集合的最佳散列算法是什么?

我正在尝试将一个不可变的multiset(这是一个包或其他语言的多重集合:像一个数学集,除了它可以容纳多个元素)作为字典实现.我已经创建了标准库类的子类collections.Counter,类似于这里的建议:Python hashable dicts,它建议像这样的哈希函数:

class FrozenCounter(collections.Counter):
    # ...
    def __hash__(self):
        return hash(tuple(sorted(self.items())))
Run Code Online (Sandbox Code Playgroud)

创建完整的项目元组会占用大量内存(相对于使用生成器而言),并且哈希将在我的应用程序的内存密集型部分中发生.更重要的是,我的字典键(multiset元素)可能不会是可订购的.

我正在考虑使用这个算法:

def __hash__(self):
    return functools.reduce(lambda a, b: a ^ b, self.items(), 0)
Run Code Online (Sandbox Code Playgroud)

我想使用按位XOR意味着顺序与散列值无关,与元组的散列不同?我想我可以在我的数据的无序流序列上半实现Python元组散列算法.请参阅https://github.com/jonashaag/cpython/blob/master/Include/tupleobject.h(在页面中搜索"hash"一词) - 但我几乎不知道有足够的C来阅读它.

思考?建议?谢谢.


(如果你想知道为什么我要乱用多线程:我的问题的输入数据是多集的集合,并且在每组多集中,每个多集必须是唯一的.我正在截止日期工作而且我不是一个经验丰富的编码员,所以我想避免在可能的情况下发明新的算法.似乎最恐怖的方式来确保我有一堆东西的独特之处就是把它们放进去set(),但事情必须是哈希的.)

我从评论中收集到了什么

@marcin和@senderle都给出了相同的答案:使用hash(frozenset(self.items())).这是有道理的,因为items()"视图"是设置的.@marcin是第一个,但我给@senderle打了一个复选标记,因为对不同解决方案的大O运行时间进行了很好的研究.@marcin还提醒我要包含一个__eq__方法 - 但是继承自的方法dict会很好用.这就是我实现所有内容的方式 - 欢迎基于此代码的进一步意见和建议:

class FrozenCounter(collections.Counter):
    # Edit: A previous version of this code included a __slots__ definition.
    # But, from the Python documentation: "When …
Run Code Online (Sandbox Code Playgroud)

python hash dictionary immutability python-3.2

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

Heroku:私有存储库中的Python依赖项,不存储我的密码

问题

我的问题与如何安装Python Heroku项目的内部需求完全一样以及如何在Heroku中部署pip的requirements.txt?.也就是说,我有一个私人仓库,我需要在我的Heroku应用程序中安装Python依赖项.Heroku自己的Kenneth Reitz给出的典型答案就是提出类似的东西

-e git+https://username:password@github.com/kennethreitz/requests.git@v0.10.0#egg=requests
Run Code Online (Sandbox Code Playgroud)

在你的requirements.txt文件中.

我的安全需求阻止我将密码存储在回购中.(我也不想将依赖项放在我的app的repo中;它们是单独的软件,需要在单独的repos中.)我唯一可以提供密码的地方(或者,最好是GitHub OAuth令牌或部署密钥)到Heroku,是在一个环境变量之类的

heroku config:add GITHUB_OAUTH_TOKEN=12312312312313
Run Code Online (Sandbox Code Playgroud)

试图解决方案

我可以.profile在我的应用程序的repo中使用自定义,但是每次进程(web,worker等)重新启动时我都会下载并安装我的依赖项.

这使得自定义buildpack和Heroku Labs插件heroku config在buildpack编译之前暴露我的环境.我尝试在Buildpack Multi构建一个.想法是Buildpack Multi是主要的buildpack,并且在我的应用程序的repo中使用该文件,它首先下载普通的Heroku Python buildpack,然后是我的自定义..buildpacks

即使在Buildpack Multi成功运行Python buildpack之后,问题仍然存在,一旦Buildpack Multi运行,我的buildpack就看不到Python二进制文件和Pip包.所以自定义buildpack完全失败了.(在我的测试中,GITHUB_OAUTH_TOKEN环境变量被正确地暴露给buildpacks.)

我能想到的唯一另一件事就是创建我自己的Python buildpack的fork,它安装我的依赖,当它安装所有东西requirements.txt,甚至requirements.txt直接重写.对于我认为是一个非常普遍的问题,这两者似乎都是非常重要的解决方案.

更新:当前的解决方法

我的自定义buildpack(上面链接)现在下载并将我的闭源依赖项("foo")保存到geos buildpack使用的供应商目录中.我在我的应用程序中提交了foo本身存在于我的应用程序中的依赖项requirements.txt.因此,Pip通过我的应用程序安装foo的依赖项requirements.txt,buildpack将foo的托管副本添加到我应用程序的环境中PYTHONPATH(所以foo setup.py install永远不会运行).

这种方法的最大问题是将我的(无可否认写得很糟糕)buildpack与我的app结合起来.第二个问题是我的应用程序requirements.txt …

python github heroku

13
推荐指数
2
解决办法
1253
查看次数

避免Python 3的多处理队列中的竞争条件

我试图找到大约61亿(自定义)项目的最大重量,我想用并行处理这样做.对于我的特定应用程序,有更好的算法,不需要我迭代超过61亿项,但解释它们的教科书是我的头脑,我的老板希望在4天内完成.我想我的公司的花哨的服务器和并行处理有更好的机会.但是,我所知道的关于并行处理的一切都来自于阅读Python 文档.这就是说我很丢失......

我目前的理论是设置一个馈送器进程,一个输入队列,一大堆(比如说30个)工作进程,以及一个输出队列(在输出队列中找到最大元素将是微不足道的).我不明白的是,馈线进程如何告诉工作进程何时停止等待项目通过输入队列.

我曾经考虑过使用multiprocessing.Pool.map_async我的6.1E9项目的迭代,但是只需要花费将近10分钟来迭代这些项目而不对它们做任何事情.除非我误解了某些东西......map_async迭代过程中将它们分配给流程可以在流程开始工作时完成.(Pool也提供imap但是文档说它类似于map,它似乎不是异步工作.我想要异步,对吗?)

相关问题:我想用concurrent.futures而不是multiprocessing吗?我不可能是第一个实施双排队系统的人(这正是美国每家熟食店的生产线如何工作......)那么有更多的Pythonic /内置方法吗?

这是我正在尝试做的一个框架.请参阅中间的注释块.

import multiprocessing as mp
import queue

def faucet(items, bathtub):
    """Fill bathtub, a process-safe queue, with 6.1e9 items"""
    for item in items:
        bathtub.put(item)
    bathtub.close()

def drain_filter(bathtub, drain):
    """Put maximal item from bathtub into drain.
    Bathtub and drain are process-safe queues.
    """
    max_weight = 0
    max_item = None
    while True:
        try: …
Run Code Online (Sandbox Code Playgroud)

python parallel-processing race-condition python-3.x

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

Pythonic,自定义警告

基本问题:制作我自己的自定义警告类的最Pythonic /逻辑方法是什么?我应该进行子类化的正确警告和异常类是什么?

动机:我正在编写的库的要求指定如果一个MyContainer对象c包含一个项目x并且库的调用者试图将"重复" x- 调用它y- 放入c,则会向调用者发出警告并且返回值c.my_transformation_method(x, y)被置于c替换中x.换句话说,MyContainers将用重复项替换元素,但必须在这样做时警告用户.

根据我的阅读,警告调用者关于非致命动作的最灵活的方法是使用警告标准模块.它允许调用者在其认为合适时处理警告,从忽略警告到将其视为错误做任何事情.(请注意,我使用的是Python 3,但我不认为这对这个问题至关重要.)

示例:我所做的是定义了以下警告子类:

class DuplicateItemWarning(UserWarning, ValueError):
    pass
Run Code Online (Sandbox Code Playgroud)

然后是检测到尝试插入重复项时add()MyContainer调用方法warnings.warn('detected duplicate', DuplicateItemWarning).

具体问题:

  1. 我应该UserWarning如上所述进行子类化,还是仅仅进行次级转换Warning

  2. 这似乎语义明智的子类ValueError(在上述例子中,仅插入ValueError之间在MRO WarningException在呼叫者想要治疗警告视为错误情况).我有没有看到这个缺点?

  3. 我在StackOverflow上找不到关于自定义警告类的任何问题.这是因为Python程序员甚至不喜欢使用该warnings模块吗?

python warnings python-3.x

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

Python 3中的不可变字典:如何使keys(),items()和values()字典视图不可变

简短版本:什么是覆盖dict.keys()和朋友的最佳方式,以防止我在Python 3中意外修改我的(据称)不可变字典?

在最近的一个问题中,我询问了如何在Python中散列不可变字典.从那时起,我已经建立了一个我不满意的不可改变,可以翻译的字典.但是,我意识到它有一个孔:在字典视图由归国keys(),items()values()仍然让自己偶然突变我(据说)不变的字典.

关于字典视图的Stack Overflow唯一的问题是Python创建自己的字典子集dict视图,但这似乎与我的问题没什么关系,以及"冻结字典"的答案是什么?似乎没有进入压倒keys()等等

这样做会阻止我意外修改,例如,我的不可变字典的键吗?

class FrozenCounter(collections.Counter):
    "Model an hashable multiset as an immutable dictionary."
    # ...
    def keys(self):
        return list(super().keys())
    def values(self):
        return list(super().values())
    def items(self):
        return list(super().items())
Run Code Online (Sandbox Code Playgroud)


我从答案中收集到了什么

我主要看不懂.

dictviews无法修改dicts.在Python 3文档中,我误读了"它们提供了对字典条目的动态视图,这意味着当字典发生更改时,视图会反映这些更改","当视图发生更改时,字典会反映这些更改." 显然,这不是文件所说的.

python dictionary immutability python-3.x

9
推荐指数
1
解决办法
7523
查看次数

Python 3中大规模,强力最大化的高效多处理

这是我最近的问题的扩展,避免了Python 3的多处理队列中的竞争条件.希望这个版本的问题更加具体.

TL; DR:在一个多处理模型中,工作进程是从队列中提供的multiprocessing.Queue,为什么我的工作进程如此空闲?每个进程都有自己的输入队列,因此它们不会为共享队列的锁而互相争斗,但队列花费大量时间实际上是空的.主进程是运行I/O绑定线程 - 是否会减慢输入队列的CPU绑定填充?

我试图在一定的约束下找到N个集合的笛卡尔乘积的最大元素,每个集合具有M_i个元素(对于0 <= i <N).回想一下,笛卡尔积的元素是长度为N的元组,其元素是N组的元素.我将这些元组称为"组合",以强调我正在循环遍历原始集合的每个组合.当我的函数is_feasible返回时,组合符合约束True.在我的问题中,我试图找到其元素具有最大权重的组合:sum(element.weight for element in combination).

我的问题规模很大,但我公司的服务器也是如此.我正在尝试将以下串行算法重写为并行算法.

from operator import itemgetter
from itertools import product # Cartesian product function from the std lib
def optimize(sets):
    """Return the largest (total-weight, combination) tuple from all
    possible combinations of the elements in the several sets, subject
    to the constraint that is_feasible(combo) returns True."""
    return max(
                map(
                    lambda combination: (
                        sum(element.weight for element in …
Run Code Online (Sandbox Code Playgroud)

python parallel-processing python-3.x

8
推荐指数
1
解决办法
1078
查看次数

Python 3:猴子修补的代码不能通过多处理重新导入

简单来说

当模块A的函数应该是可导入的时候,如何从模块B中获取补丁模块A,以便我可以使用multiprocessing标准库包运行模块A的函数?

背景

客户端请求了一个不适用于我们任何其他客户端的修补程序,因此我创建了一个新分支,并为它们编写了一个单独的模块,以便从主分支中轻松合并更改.为了保持客户端与预修复程序行为的向后兼容性,我在应用程序中将此修补程序实现为可配置设置.因此,我不想替换旧代码 - 只需在打开设置时对其进行修补即可.我通过猴子修补做到了这一点.

代码结构

__main__模块读入配置文件.如果配置打开了修补程序的开关,则通过用模块中定义的代码替换几个函数来__main__修补我enginehotfix模块 - 实质上,被替换的函数是最大化函数关键函数.该engine模块稍后会加载一个工作池multiprocessing.

问题

一旦multiprocessing工作人员开始工作,第一件事multiprocessing就是重新导入*engine模块并查找__main__试图替换的关键功能(然后multiprocessing将控制交给我的代码并开始最大化算法).由于engine正在通过一个全新的流程重新导入,并且新流程不会重新运行__main__(配置文件被读取的地方)因为这会导致无限循环,所以它不知道重新进行猴子补丁engine.

问题

如何在代码中保持模块化(即,将修补程序代码保存在单独的模块中)并仍然利用Python的multiprocessing包?

*注意我的代码必须在Windows(对我的客户端)和Unix(为了我的理智......)上工作

python import monkeypatching multiprocessing python-3.x

8
推荐指数
1
解决办法
437
查看次数

Django-无法打开数据库文件(sqlite3.OperationalError)

我正在使用django框架开发一个小型应用程序,当尝试通过Apache2服务时,出现以下错误:

(sqlite3.OperationalError)无法打开数据库文件(此错误的背景位于:http : //sqlalche.me/e/e3q8

settings.py输入的数据库如下所示:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3')
    }
}
Run Code Online (Sandbox Code Playgroud)

该数据库文件存在,并具有chmod赋予的以下权限:

root@myVPS:/var/www/lab# ls -l db.sqlite3
total 30236
-rwxrwxr-x 1 www-data www-data  3018568 Jul  1 22:14 db.sqlite3
Run Code Online (Sandbox Code Playgroud)

根文件夹/var/www/lab

drwxrwxr-x 8 www-data www-data 4096 Jul 2 01:15 lab
Run Code Online (Sandbox Code Playgroud)

我读到版权可能有问题,但我似乎找不到我做错了什么。

我的Apache2配置文件:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName sub.domain.com
        ServerAlias sub.domain.com
        DocumentRoot /var/www/lab
        <Directory /var/www/lab>
                Options FollowSymLinks
                AllowOverride All
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order …
Run Code Online (Sandbox Code Playgroud)

python sqlite django python-3.x

6
推荐指数
0
解决办法
303
查看次数