小编Sno*_*gus的帖子

猴子在Python中修补另一个模块中的一个类

我正在使用其他人编写的模块.我想修补__init__模块中定义的类的方法.我发现如何执行此操作的示例都假设我自己会调用该类(例如,Monkey-patch Python类).然而,这种情况并非如此.在我的情况下,该类在另一个模块中的函数内被初始化.请参阅下面的(大大简化)示例:

thirdpartymodule_a.py

class SomeClass(object):
    def __init__(self):
        self.a = 42
    def show(self):
        print self.a
Run Code Online (Sandbox Code Playgroud)

thirdpartymodule_b.py

import thirdpartymodule_a
def dosomething():
    sc = thirdpartymodule_a.SomeClass()
    sc.show()
Run Code Online (Sandbox Code Playgroud)

mymodule.py

import thirdpartymodule_b
thirdpartymodule.dosomething()
Run Code Online (Sandbox Code Playgroud)

有没有办法修改__init__方法,SomeClass以便dosomething从mymodule.py调用它时,例如,打印43而不是42?理想情况下,我能够包装现有方法.

我无法更改thirdpartymodule*.py文件,因为其他脚本依赖于现有功能.我宁愿不必创建我自己的模块副本,因为我需要做的改变非常简单.

编辑2013-10-24

我忽略了上面例子中的一个小而重要的细节.SomeClass是这样导入的thirdpartymodule_b:from thirdpartymodule_a import SomeClass.

要做FJ建议的补丁我需要替换副本thirdpartymodule_b,而不是thirdpartymodule_a.例如thirdpartymodule_b.SomeClass.__init__ = new_init.

python unit-testing monkeypatching class

61
推荐指数
3
解决办法
4万
查看次数

使用distutils和build_clib来构建C库

有没有人有一个很好的例子,build_clib在distutils 中使用命令从setup.py构建一个外部(非python)C库?关于这个问题的文件似乎很少或根本不存在.

我的目标是构建一个非常简单的外部库,然后构建一个链接到它的cython包装器.我发现的最简单的例子就是这里,但这使用了system()对gcc 的调用,我无法想象这是最佳实践.

python cython

16
推荐指数
1
解决办法
2673
查看次数

使用PyPDF2添加书签

PyPDF2的文档声明可以将嵌套书签添加到PDF文件中,并且代码出现(在阅读时)以支持这一点.

将书签添加到根树很容易(参见下面的代码),但我无法弄清楚我需要传递什么作为parent创建嵌套书签的参数.我想创建一个像这样的结构:

Group A
    Page 1
    Page 2
Group A
    Page 3
    Page 4 
Run Code Online (Sandbox Code Playgroud)

这可能吗?

将书签添加到树根的示例代码:

#!/usr/bin/env python
from PyPDF2 import PdfFileWriter, PdfFileReader
output = PdfFileWriter() # open output
input = PdfFileReader(open('input.pdf', 'rb')) # open input
output.addPage(input.getPage(0)) # insert page
output.addBookmark('Hello, World', 0, parent=None) # add bookmark
Run Code Online (Sandbox Code Playgroud)

PyPDF2 addBookmark功能:https://github.com/mstamy2/PyPDF2/blob/master/PyPDF2/pdf.py#L517

python pdf

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

添加对视网膜显示器(HiDPI)的支持到现有的Qt4应用程序

升级现有的Qt4应用程序以在OS X上使用视网膜显示器需要做什么?

Qt博客说Qt 4.8"有很好的支持,并且有一些Qt 5补丁的后端可用":

http://blog.qt.digia.com/blog/2013/04/25/retina-display-support-for-mac-os-ios-and-x11/

我添加了以下Info.plist似乎工作.文本和按钮不再像素化.

<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
Run Code Online (Sandbox Code Playgroud)

我正在努力的是让图标/ pixmaps很好地渲染.我使用Qt Designer创建了UI.我不知道如何让应用程序识别@ 2x图标.

我想要升级的应用程序是用C++(https://github.com/qgis/QGIS)编写的,但我也一直在使用Python(PyQt4)进行测试.QPixamp实例似乎没有setDevicePixelRatio方法.

我正在运行OS X(10.9.4),通过Homebrew安装Qt 4.8.

c++ qt4 qgis retina-display

8
推荐指数
0
解决办法
2044
查看次数

初始化和销毁​​Python多处理工作程序

我有一个模型,我从Python多次调用.该模型需要很长时间才能启动和关闭,但只需很短的时间来处理输入数据(可以在启动/关闭之间多次完成).多处理Pool()似乎是完成这项工作的好方法,但是我无法正确地将Model()类转换为destory.

下面给出了程序代码的简化结构.实际上,init和del函数需要使用win32com.client模块做一些聪明的事情,而model.y变量是控制外部应用程序的句柄.

#!/usr/bin/env python

import multiprocessing
import random
import time

class Model():
    def __init__(self):
        self.y = random.randint(0,5) # simplification
        time.sleep(5) # initialisation takes a while...
    def __del__(self):
        del(self.y) # simplification
        time.sleep(1) # destruction isn't especially quick either

def init():
    global model
    model = Model()

def f(x): # worker function, runs quickly
    return model.y * x ** 2

def main():
    pool = multiprocessing.Pool(processes=2, initializer=init)
    it = pool.imap(f, range(4))
    for n in range(4):
        print it.next()
    pool.close()

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

从来没有为Model()调用del函数,我猜是因为垃圾收集器中存在一些引用.如何确保在程序结束时正确关闭模型?

python multiprocessing

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

在 cython 类中包装一个预初始化的指针

我正在尝试使用一个 C 库,它使用一个回调函数 (callback_function) 来提供一个指向我想要包装的结构 (glp_tree) 的指针。

使用未在 中创建的指针初始化实例的正确方法是什么__cinit__?我在 cython 文档中找不到这种模式的例子。

我有一些工作代码(见下文),它将指针转换为整数并返回,但我不确定这是好的做法/理智。

cdef extern from "stdint.h":
    ctypedef unsigned long long uint64_t

cdef extern from "glpk.h":
    ctypedef struct glp_tree:
        pass

cdef void callback_func(glp_tree* tree, void *info):
    treeobj = Tree(<uint64_t>tree) // cast to an integer...

cdef class Tree:
    cdef glp_tree* ptr
    def __init__(self, uint64_t ptr):
        self.ptr = <glp_tree*>ptr // ... and back to a pointer
Run Code Online (Sandbox Code Playgroud)

直接传递 glp_tree 对象似乎可以工作(虽然这不是我想要做的),但是尝试传递指针会导致编译器错误:

Cannot convert 'glp_tree *' to Python object
Run Code Online (Sandbox Code Playgroud)

c python pointers cython

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

如何使用Cython进行覆盖率分析

我正在尝试使用pytest-cov和coveralls.io对一些Cython代码进行覆盖率分析.我已经建立了启用跟踪的扩展模块,并在以下链接的帮助下运行分析:

http://docs.cython.org/src/tutorial/profiling_tutorial.html

http://blog.behnel.de/posts/coverage-analysis-for-cython-modules.html

但是,我得到了一些我无法解释的结果.似乎代码中的许多def/ cdef/ cpdef行显示为未运行,尽管其中的代码正常.结果甚至不一致,因为有些线条似乎没问题.

示例报告:https://coveralls.io/files/1871744040

我不知道我是否说错了,如果这是一个错误,或者我只是没有正确地解释结果.

工作服截图

在上面的示例中,该get_cost方法看起来没问题,但是__set__上面的属性的方法没有被调用,尽管已经调用了函数中的行.

更新:似乎问题出在Cython类上.如果定义了类def而不是cdef问题消失了.我想还没有完全支持.

code-coverage cython

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

使用 win32com.client.gencache.EnsureDispatch 时出现类型不匹配错误

我正在尝试使用 win32com 模块与专有应用程序的 COM 接口进行交互。我可以使用动态代理(win32com.client.Dispatch)连接到接口,这似乎可以工作。但是,如果我可以使用静态代理,这将很有用,尤其是因为它填充了 help() 页面。

我可以与动态代理正常交互:

>>> import win32com.client
>>> aqt = win32com.client.Dispatch("Aquator.Application")
>>> db = aqt.LoadDatabase(Folder=r"D:\Shared", Name="AquatorExcel.mdb")
>>> db.Name
u'D:\\Shared\\AquatorExcel.mdb'
>>> db.GetProjectList()
(1, (3,), (u'A simple model',))
Run Code Online (Sandbox Code Playgroud)

但是,当我使用通过 EnsureDispatch 或 makepy 脚本生成的静态代理时,出现以下错误:

>>> import win32com.client
>>> aqt = win32com.client.gencache.EnsureDispatch("Aquator.Application")
>>> db.Name
u'D:\\Shared\\AquatorExcel.mdb'
>>> db = aqt.LoadDatabase(Folder=r"D:\Shared", Name="AquatorExcel.mdb")
>>> db.GetProjectList()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Pythonxy\Pythonxy 2.7\Python27\lib\site-packages\win32c
om\gen_py\AE9A7F2A-5DD7-4658-B55C-216CAD680889x0x4x3\_Database.py", line 70, in
GetProjectList
    , NameList)
  File "C:\Program Files\Pythonxy\Pythonxy 2.7\Python27\lib\site-packages\win32c
om\client\__init__.py", line …
Run Code Online (Sandbox Code Playgroud)

python com

5
推荐指数
0
解决办法
4087
查看次数

在QDialog reject()上正常终止QThread

我有一个QDialog创建一个QThread来做一些工作,同时保持UI响应,基于这里给出的结构:如何真正,真正使用QThreads; 完整解释.但是,如果在线程仍在运行时调用reject()(由于用户按下取消或关闭对话框),则会出现错误:

QThread:线程仍在运行时被销毁

我想要发生的是工作中的循环提前中断,然后在后台进行一些清理(例如清除一些队列,发出信号).我已经设法用我自己的"取消"功能来做到这一点,但是如何让它与reject()(以及它可以调用的所有方法)很好地配合?我不希望对话框阻止等待清理 - 它应该继续在后台运行,然后优雅地退出.

请参阅下面显示问题的示例代码.任何帮助将不胜感激.

#!/usr/bin/env python

from PyQt4 import QtCore, QtGui
import sys
import time

class Worker(QtCore.QObject):
    def __init__(self):
        QtCore.QObject.__init__(self)

    def process(self):
        # dummy worker process
        for n in range(0, 10):
            print 'process {}'.format(n)
            time.sleep(0.5)
        self.finished.emit()

    finished = QtCore.pyqtSignal()

class Dialog(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        self.init_ui()

    def init_ui(self):
        self.layout = QtGui.QVBoxLayout(self)
        self.btn_run = QtGui.QPushButton('Run', self)
        self.layout.addWidget(self.btn_run)
        self.btn_cancel = QtGui.QPushButton('Cancel', self)
        self.layout.addWidget(self.btn_cancel)

        QtCore.QObject.connect(self.btn_run, QtCore.SIGNAL('clicked()'), self.run)
        QtCore.QObject.connect(self.btn_cancel, QtCore.SIGNAL('clicked()'), self.reject)

        self.show()
        self.raise_()

    def run(self):
        # start the worker thread …
Run Code Online (Sandbox Code Playgroud)

python qt multithreading pyqt

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

用一个月而不是一年创建大熊猫时间序列

使用pandas我可以使用datetime对象(包含月份和日期)索引时间序列并获取句点的值,例如:

from pandas import *
ts = TimeSeries([41,45,48],[Period('2012'),Period('2013'),Period('2014')])
print ts[datetime(2013,05,17)]
Run Code Online (Sandbox Code Playgroud)

有没有办法定义一个月但没有一年的时期?我有一个月平均频率,我希望能够按月/日编制索引,例如:

ts = TimeSeries(range(1,13),[Period(month=n,freq='M') for n in range(1,13)])
print ts[datetime(2013,05,17)]
Run Code Online (Sandbox Code Playgroud)

Period对象似乎不支持此(它会引发错误).有没有比使用一年创建时间序列更好的方法,然后在用于索引时间序列之前修改datetime对象?

http://pandas.pydata.org/pandas-docs/dev/timeseries.html#period

编辑1:

为了澄清我为什么要这样做:我有一个模型,它计算每日时间步.我在模型中有一个变量,它是表示当天的日期时间对象.我需要在几个时间序列中查看当前日期,其中一些时间序列有完整的日期(年/月/日),但其他时间只有一个月.我希望有一些像索引一样无缝的东西,因为时间序列/配置文件是由用户在运行时提供的.我已经完成了覆盖__getitem__TimeSeries对象的方法(这样我可以解决幕后的岁月),但这似乎有点疯狂.

from pandas import *

class TimeSeriesProfile(TimeSeries):
    year = 2004

    def __new__(self, *args, **kwargs):
        inst = TimeSeries.__new__(self, *args, **kwargs)
        inst.index = period_range(str(self.year)+str(inst.index[0])[4:], periods=len(inst.index), freq=inst.index.freq)
        return inst.view(TimeSeriesProfile)

    def __getitem__(self, key):
        without_year = datetime(self.year, key.month, key.day, key.hour, key.minute, key.second)
        return TimeSeries.__getitem__(self, without_year)

ts = TimeSeriesProfile(range(0, 366), period_range('1996-01-01', periods=366, freq='D'))

print ts[datetime(2008, 02, 29)]
Run Code Online (Sandbox Code Playgroud)

python datetime pandas

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

未加载库:libmkl_intel_lp64.dylib,在OS X上使用Anaconda

我无法在OS X(10.11.3)上使用支持MKL的NumPy版本.模块似乎安装正常,但当我尝试导入它时,我得到错误Library not loaded: @loader_path/../../../../libmkl_intel_lp64.dylib.实际上,如果我搜索这个文件(mdfind -name libmkl_intel_lp64.dylib),则不会返回任何内容.这是包或我的安装有问题吗?同样的过程在我的Windows机器上完美运行.我能够nomkl毫无困难地安装构建并导入它,但我想使用MKL(如果有的话).

编辑:从mkl包(http://anaconda.org/anaconda/mkl/files)手动安装dylib 似乎工作 - 也许这是一个错误?

安装NumPy:

snorfmac-2:~ snorf$ source activate snowflake
discarding /Users/snorf/miniconda3/bin from PATH
prepending /Users/snorf/miniconda3/envs/snowflake/bin to PATH
(snowflake)snorfmac-2:~ snorf$ conda install numpy
Using Anaconda Cloud api site https://api.anaconda.org
Fetching package metadata: ......
Solving package specifications: .............
Package plan for installation in environment /Users/snorf/miniconda3/envs/snowflake:

The following NEW packages will be INSTALLED:

    mkl:   11.3.1-0     
    numpy: 1.10.4-py34_0

Proceed ([y]/n)? 

Linking packages ...
[      COMPLETE      ]|###################################################| …
Run Code Online (Sandbox Code Playgroud)

python numpy anaconda

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

不同平台上按钮的顺序(QDialogBu​​ttonBox)

QDialogBu​​ttonBox 小部件会自动重新排序其按钮,以满足不同平台上用户的期望。我想遵循这种行为,但使用我自己的按钮标签(例如“导入”而不是“确定”)。我怎样才能实现这个目标?是否可以使用 QMessageBox,还是我需要编写自己的实现?我正在使用 PyQt4 和 Qt Designer 编写我的应用程序。

请参阅下面 OS X 上 QDialogBu​​ttonBox 的 Aqua 和 Cleanlooks 风格的屏幕截图。

QDialogBu​​ttonBox

python qt pyqt4

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