我正在编写自己的容器,需要通过属性调用来访问内部的字典.容器的典型用法如下:
dict_container = DictContainer()
dict_container['foo'] = bar
...
print dict_container.foo
Run Code Online (Sandbox Code Playgroud)
我知道写这样的东西可能是愚蠢的,但这是我需要提供的功能.我正在考虑以下列方式实现它:
def __getattribute__(self, item):
try:
return object.__getattribute__(item)
except AttributeError:
try:
return self.dict[item]
except KeyError:
print "The object doesn't have such attribute"
Run Code Online (Sandbox Code Playgroud)
我不确定嵌套的try/except块是否是一个好习惯,所以另一种方法是使用hasattr()
和has_key()
:
def __getattribute__(self, item):
if hasattr(self, item):
return object.__getattribute__(item)
else:
if self.dict.has_key(item):
return self.dict[item]
else:
raise AttributeError("some customised error")
Run Code Online (Sandbox Code Playgroud)
或者使用其中一个和一个尝试catch块,如下所示:
def __getattribute__(self, item):
if hasattr(self, item):
return object.__getattribute__(item)
else:
try:
return self.dict[item]
except KeyError:
raise AttributeError("some customised error")
Run Code Online (Sandbox Code Playgroud)
哪个选项最pythonic和优雅?
我有一个包含数字的字符串列表,我找不到对它们进行排序的好方法.
例如,我得到这样的东西:
something1
something12
something17
something2
something25
something29
Run Code Online (Sandbox Code Playgroud)
用这个sort()
方法.
我知道我可能需要以某种方式提取数字,然后对列表进行排序,但我不知道如何以最简单的方式进行.
最近,当我使用多处理模块和mpi4py作为通信工具测量并行应用程序的性能时,我观察到了一种奇怪的效果.
该应用程序对数据集执行进化算法.除评估外,大多数操作都是按顺序完成的.在应用所有进化运算符之后,所有个体都需要接收新的适应值,这在评估期间完成.基本上它只是在浮点列表(python之类)上执行的数学计算.在评估之前,数据集由mpi的scatter或python的Pool.map分散,然后进行并行评估,之后数据通过mpi的聚集或Pool.map机制返回.
我的基准平台是运行Ubuntu 11.10的虚拟机(虚拟机),在Core i7(4/8内核)上运行Open MPI 1.4.3,8 GB内存和SSD驱动器.
我发现真正令人惊讶的是,我获得了一个很好的加速,但是根据通信工具,在一定的进程阈值之后,性能变得更糟.它可以通过下面的图片来说明.
y轴 - 处理时间
x轴 - 过程
颜色的nr - 每个个体的大小(浮动的nr)
1)使用多处理模块 - Pool.map
2)使用mpi - Scatter/Gather
3)两张照片在彼此的顶部
起初我认为它是超线程的错误,因为对于大型数据集,它在达到4个进程(4个物理内核)后变得更慢.但是它应该在多处理情况下也可见,而事实并非如此.我的另一个猜测是mpi通信方法比python方法效果差得多,但我发现很难相信.
有没有人对这些结果有任何解释?
添加:
毕竟我开始相信这是超线程故障.我在具有核心i5(2/4核心)的机器上测试了我的代码,并且在3个或更多进程中性能更差.我想到的唯一解释是,我使用的i7没有足够的资源(缓存?)来与超线程同时计算评估,需要安排4个以上的进程在4个物理内核上运行.
然而有趣的是,当我使用mpi htop显示完全利用所有8个逻辑核心时,这应该表明上述语句是不正确的.另一方面,当我使用Pool.Map时,它并没有完全利用所有核心.它使用一个或2个最大值而其余部分仅使用部分,再次不知道它为什么会这样.明天我将附上显示此行为的屏幕截图.
我没有在代码中做任何花哨的东西,它真的很简单(我不是因为它的秘密,而是因为它需要安装DEAP之类的其他库而不是给出整个代码.如果有人真的对这个问题感兴趣并准备好了安装DEAP我可以准备一个简短的例子).MPI的代码有点不同,因为它无法处理填充容器(从列表继承).当然有一些开销,但没什么大不了的.除了我在下面显示的代码,其余部分是相同的.
Pool.map:
def eval_population(func, pop):
for ind in pop:
ind.fitness.values = func(ind)
return pop
# ...
self.pool = Pool(8)
# ...
for iter_ in xrange(nr_of_generations):
# ...
self.pool.map(evaluate, pop) # evaluate is really an eval_population alias with a certain function assigned to its first argument.
# ...
Run Code Online (Sandbox Code Playgroud)
MPI - …
我的几个剧本都有这样的子剧结构:
- hosts: sites
user: root
tags:
- configuration
tasks:
(...)
- hosts: sites
user: root
tags:
- db
tasks:
(...)
- hosts: sites
user: "{{ site_vars.user }}"
tags:
- app
tasks:
(...)
Run Code Online (Sandbox Code Playgroud)
在Ansible 1.x中,管理员和开发人员都能够使用这样的剧本.管理员可以使用所有标记(root和用户访问)运行它,而开发人员只能访问最后一个标记,其中任务位于用户访问级别.当开发人员使用app标签运行此playbook时,前两个标签会跳过收集事实.然而,现在,在Ansible 2.1中,它没有被跳过,这导致没有root访问权限的用户失败.
是否有机制或简单修改来解决此问题?现在是否应该采用一种新方法应用于此类案件?
我想知道你是否在你的代码中使用@staticmethod装饰器.
就个人而言,我不使用它,因为它需要更多的信件来写@staticmethod然后自己.
使用它的唯一好处(来自我)可能是更好的代码清晰度,但由于我经常为sphinx编写方法描述,我总是说明一个方法是否正在使用对象.
或者也许我应该开始使用@staticmethod装饰器?
我正在尝试在sphinx中为我的项目编写文档,每当sphinx在我的模块中遇到OptionParser时,它就会给我:
sphinx-build: error: no such option: -b
Run Code Online (Sandbox Code Playgroud)
我认为这是不可能的,所以我写了一个简单的模块来检查:
from optparse import OptionParser
"""some comment here"""
parser = OptionParser(conflict_handler='resolve')
parser.add_option('', '--force', action='store_true', dest='force', default=False, help='gqdel will skip asking questions, and delete them all.');
parser.add_option('', '--verbose', action='store_true', dest='verbose', default=False, help='Report additional information from gqdel')
(options, args) = parser.parse_args()
"""and here"""
print "foo"
Run Code Online (Sandbox Code Playgroud)
它给了我同样的错误.我的第一个看起来像这样:
some title
==========
.. automodule:: test
:members:
Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我使用多处理模块中的管道来在python进程之间进行通信.最近我发现了一种奇怪的行为,这取决于我通过它们发送的数据的大小.根据python文档,这些管道基于连接,并且应该以异步方式运行,但有时它们会在发送时陷入困境.如果我在每个连接中启用全双工,一切正常,即使我没有使用连接进行发送和收听.谁能解释这种行为?
代码(这不是我的生产代码,它只是说明了我的意思):
from collections import deque
from multiprocessing import Process, Pipe
from numpy.random import randn
from os import getpid
PROC_NR = 4
DATA_POINTS = 100
# DATA_POINTS = 10000
def arg_passer(pipe_in, pipe_out, list_):
my_pid = getpid()
print "{}: Before send".format(my_pid)
pipe_out.send(list_)
print "{}: After send, before recv".format(my_pid)
buf = pipe_in.recv()
print "{}: After recv".format(my_pid)
if __name__ == "__main__":
pipes = [Pipe(False) for _ in range(PROC_NR)]
# pipes = [Pipe(True) for _ in …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用777权限创建目录.
os.mkdir(Xmldocument.directory, 0777)
Run Code Online (Sandbox Code Playgroud)
但是我得到的是775
drwxrwxr-x. 2 mwysoki mwysoki 4096 Nov 9 11:38 VeloDBBrowser
Run Code Online (Sandbox Code Playgroud)
我确信我拥有适当的权利,因为chmod 777工作得很好.
我正在编写一个使用PyQt4进行GUI的linux应用程序,它只在远程会话期间使用
(ssh -XY/vnc).
因此,有时可能会发生用户忘记使用X转发参数运行ssh或者由于某种原因X转发将无法使用的情况.在这种情况下,应用程序崩溃严重(不幸的是我强行使用包装到python中的旧C++库,如果应用程序崩溃,它会完全混淆用户的当前会话).
我不能使用其他东西所以我的想法是在加载该库之前检查X转发是否可用.但是我不知道该怎么做.
我通常使用xclock检查我的会话是否启用了X转发,但使用xclock听起来像一个大的解决方法.
添加
如果可能,我想使用另一种方法,而不是创建一个空的PyQt窗口并捕获异常.
我需要在单个R会话中创建多个临时目录,但是每次调用tempdir()时,我都会得到相同的目录。
有没有一种简单的方法来确保每个呼叫都会给我一个新的临时目录?