小编Jam*_*mes的帖子

我什么时候需要在Tkinter应用程序中调用mainloop?

每个tkinter教程我都看到了tkinter.mainloop必须要求绘制窗口和要处理的事件的声明,并且它们总是调用此函数,即使在hello world程序中也是如此.但是,当我在交互式shell中尝试这些时,无需调用mainloop即可正确绘制窗口. 这个在tkinter中嵌入matplotlib图形的例子产生了一个相对复杂的应用程序,带有用于在tkinter窗口内平移,缩放和调整绘图大小的按钮,再次,如果你删除对mainloop的调用并在交互式shell中运行代码,这一切都有效. .当然,如果我在交互式shell之外运行脚本(删除了mainloop),程序结束得太快就看不到会发生什么,但如果我添加一个调用input 保持程序打开一切正常(我在Linux上运行python 3.2.2).

那么mainloop到底做了什么,什么时候需要调用呢?

编辑:澄清一下,如果我打开GNOME终端并输入

$python3
>>> import tkinter
>>> root = tkinter.Tk()
Run Code Online (Sandbox Code Playgroud)

一个窗口立即出现,而不必调用mainloop,更复杂的tkinter功能似乎也可以工作(例如,向窗口添加按钮).在IDLE中,需要调用mainloop.我的理解是,在调用mainloop之前,不应绘制任何内容,也不应处理任何事件.

python tkinter

41
推荐指数
2
解决办法
8万
查看次数

为什么Ellipsis和NotImplemented不能被腌制?

我很惊讶地发现python(版本3.2.2)拒绝挑选一个对象,因为它的dict包含一个引用Ellipsis.其他的内置常量,泡菜是乐意与合作False,True以及None作为中明确规定泡菜的文档,也扼流圈NotImplemented.

Python 3.2.2 (default, Sep  5 2011, 21:17:14) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.dumps(True)
b'\x80\x03\x88.'
>>> pickle.dumps(False)
b'\x80\x03\x89.'
>>> pickle.dumps(None)
b'\x80\x03N.'
>>> pickle.dumps(Ellipsis)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'ellipsis'>: attribute lookup builtins.ellipsis failed
>>> pickle.dumps(NotImplemented)
Traceback (most recent call last):
  File "<stdin>", line 1, …
Run Code Online (Sandbox Code Playgroud)

python pickle

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

Python - 一个对象可以是它自己的类型吗?

我在CPython 3.2.2中玩过元类,我发现有可能最终得到一个类型为自己的类:

Python 3.2.2 (default, Sep  5 2011, 21:17:14) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class MC(type):            #a boring metaclass that works the same as type
...     pass
... 
>>> class A(MC, metaclass=MC): #A is now both a subclass and an instance of MC...
...     pass
...
>>> A.__class__ = A            #...and now A is an instance of itself?
>>> A is type(A)
True
Run Code Online (Sandbox Code Playgroud)

对于我们的元类A,类和实例属性之间似乎没有太大的区别:

>>> A.__next__ = lambda self: …
Run Code Online (Sandbox Code Playgroud)

python recursion metaclass class

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

Python:赋值中的异常

如果我尝试以下代码(在Python 3.2.2中),

def f():
    raise Exception

x = f()
Run Code Online (Sandbox Code Playgroud)

然后它似乎没有x被触及 - 它要么保持未定义,要么保留它以前的任何值.只要赋值的右侧抛出异常,这种行为是否得到保证?我意识到这是一个非常基本的问题,但我找不到有关分配工作原理的详细信息.更一般地说,在与任务相关的任何事情发生之前,是否总是评估整个右侧?在使用setattr,分配列表元素或使用元组解包(即类似的东西x, y = y, f())时,这是否正确?

python exception-handling exception

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

Python中的持久性memoization

我有一个昂贵的函数,它接收并返回少量数据(一些整数和浮点数).我已经记住了这个功能,但我想让备忘录持久化.已经有几个与此相关的线程,但我不确定某些建议方法的潜在问题,我有一些相当具体的要求:

  • 我肯定会同时使用来自多个线程和进程的函数(使用multiprocessing和来自不同的python脚本)
  • 我不需要从这个python函数外部读取或写入对备忘录的访问权限
  • 我并不担心备忘录在极少数情况下会被破坏(比如拉动插头或意外地写入文件而不锁定它),因为重建并不是那么昂贵(通常是10-20分钟),但我更愿意,如果它不会因为异常而被破坏,或者手动终止python进程(我不知道它有多现实)
  • 我非常喜欢不需要大型外部库的解决方案,因为我在一台机器上的硬盘空间非常有限,我将运行代码
  • 我对跨平台代码的偏好很弱,但我可能只会在Linux上使用它

该主题讨论了该shelve模块,该模块显然不是过程安全的.其中两个答案建议使用fcntl.flock锁定搁置文件.然而,这个帖子中的一些回答似乎表明这充满了问题 - 但我不确定它们是什么.这听起来好像只限于Unix(虽然显然Windows有一个等效的称为msvcrt.locking),而锁只是'建议' - 即它不会阻止我在不检查它被锁定的情况下意外写入文件.还有其他潜在的问题吗?写入文件的副本,并将主副本替换为最后一步,是否会降低腐败风险?

看起来dbm模块看起来不比搁置更好.我已经快速浏览了sqlite3,但为此目的看起来有点过分. 这个帖子这个提到了几个第三方库,包括ZODB,但是有很多选择,而且它们对于这个任务来说都显得过于庞大和复杂.

有人有建议吗?

更新:有点提到下面的IncPy,看起来非常有趣.不幸的是,我不想回到Python 2.6(我实际上使用3.2),看起来使用C库有点尴尬(我大量使用numpy和scipy等).

kindall的另一个想法是有启发性的,但我认为将其调整为多个进程会有点困难 - 我想用文件锁定或数据库替换队列是最容易的.

再次看ZODB,它确实看起来非常适合这项任务,但我确实希望避免使用任何其他库.我还不完全确定简单使用的所有问题是什么flock- 我想象一个大问题是如果一个进程在写入文件时终止,或者在释放锁之前?

所以,我已经采用了synthesizerpatel的建议并且使用了sqlite3.如果有人感兴趣的话,我决定直接替换dict它将其条目存储为数据库中的泡菜(我不打算留在内存中,因为数据库访问和酸洗比我正在做的其他事情都要快).我确信有更有效的方法可以做到这一点(我不知道我是否仍然会遇到并发问题),但这里是代码:

from collections import MutableMapping
import sqlite3
import pickle


class PersistentDict(MutableMapping):
    def __init__(self, dbpath, iterable=None, **kwargs):
        self.dbpath = dbpath
        with self.get_connection() as connection:
            cursor = connection.cursor()
            cursor.execute(
                'create table if …
Run Code Online (Sandbox Code Playgroud)

python concurrency persistence memoization file-locking

10
推荐指数
2
解决办法
2269
查看次数

Numpy多维数组切片

假设我已经定义了一个3x3x3 numpy数组

x = numpy.arange(27).reshape((3, 3, 3))
Run Code Online (Sandbox Code Playgroud)

现在,我可以得到一个包含每个3x3子阵列的(0,1)元素的数组x[:, 0, 1],它返回array([ 1, 10, 19]).如果我有一个元组(m,n)并想要检索存储在元组中的每个子数组(0,1)的(m,n)元素,该怎么办?

例如,假设我有t = (0, 1).我试过x[:, t],但它没有正确的行为 - 它返回每个子数组的行0和1.我发现最简单的解决方案是

x.transpose()[tuple(reversed(t))].transpose()
Run Code Online (Sandbox Code Playgroud)

但我相信一定有更好的方法.当然,在这种情况下,我能做到x[:, t[0], t[1]],但不能一概而论的地方,我不知道有多少尺寸的情况下x,并t有.

python arrays indexing numpy multidimensional-array

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

如何找到传递给函数的变量的名称?

在C/C++中,我经常发现它在调试时有用,比如定义一个宏,ECHO(x)打印出变量名及其值(即ECHO(variable)可能打印variable 7).您可以使用"字符串化操作符的宏来得到变量名#描述这里.有没有办法在Python中这样做?

换句话说,我想要一个功能

def echo(x):
    #magic goes here
Run Code Online (Sandbox Code Playgroud)

如果被称为foo=7; echo(foo)(或foo=7; echo('foo')可能),将打印出来foo 7.我意识到如果我将变量及其名称都传递给函数,这样做是微不足道的,但是在调试时我会使用这样的函数,重复总是会让我感到恼火.

python reflection variables

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

concurrent.futures代码中的死锁

我一直在尝试使用一些代码并行化,concurrent.futures.ProcessPoolExecutor但一直没有出现奇怪的死锁ThreadPoolExecutor.一个最小的例子:

from concurrent import futures

def test():
    pass

with futures.ProcessPoolExecutor(4) as executor:
    for i in range(100):
        print('submitting {}'.format(i))
        executor.submit(test)
Run Code Online (Sandbox Code Playgroud)

在蟒蛇3.2.2(在64位的Ubuntu),这似乎在提交的所有作业后,始终悬挂-这似乎发生每当提交的作业数量比工人的数量.如果我ProcessPoolExecutorThreadPoolExecutor它替换它完美无瑕.

作为调查的尝试,我给每个未来一个回调打印值i:

from concurrent import futures

def test():
    pass

with futures.ProcessPoolExecutor(4) as executor:
    for i in range(100):
        print('submitting {}'.format(i))
        future = executor.submit(test)

        def callback(f):
            print('callback {}'.format(i))
        future.add_done_callback(callback)
Run Code Online (Sandbox Code Playgroud)

这让我更加困惑 - i打印出来callback的值是它被调用时的值,而不是它被定义的时间(所以我从来没有看到,callback 0但我得到了很多callback 99s).再次,ThreadPoolExecutor打印出预期值.

想知道这可能是一个bug,我尝试了python的最新开发版本.现在,代码至少似乎终止了,但我仍然得到错误的i打印值.

任何人都可以解释:

  • ProcessPoolExecutor在python 3.2和当前开发版本之间发生了什么,显然修复了这个死锁

  • 为什么i要打印'错误'的价值 …

python multiprocessing concurrent.futures

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

使用matplotlib API在屏幕上绘制图表

我知道如何使用pyplot界面在屏幕上显示matplotlib图(我想!).我开始在一个多线程程序中绘图,这开始导致错误,所以我试图切换到面向对象的界面.我可以制作一个简单的情节并保存到文件中使用

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

fig = Figure()
can = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot((1,2,3))
can.print_figure('test')
Run Code Online (Sandbox Code Playgroud)

但是如何在屏幕上显示此图?我见过其他使用过can.draw()但没有效果的代码.

另外,请告诉我上面的代码是否有任何不理想 - 我还没有真正掌握所有这些图形,画布和轴对象的功能.

python matplotlib

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

为什么tkinter不能很好地处理多处理?

以下代码挂起而没有在linux中的python 3.2.2中做任何事情:

import tkinter
from multiprocessing import Process

def f():
    root = tkinter.Tk()
    label = tkinter.Label(root)
    label.pack()
    root.mainloop()

p = Process(target=f)
p.start()
Run Code Online (Sandbox Code Playgroud)

我发现的关于这个问题的唯一信息是问题5527,其中注意到问题是tkinter在进程分叉之前导入,可以通过tkinter在函数内部导入来修复f,并且问题发生在Linux但是不是Solaris.

有谁知道究竟是什么导致了这个问题,如果它是有意的还是最终会被修复?除了tkinter在我需要它的地方进行本地导入(这看起来像坏样式)之外,还有其他解决方法吗?是否有任何其他模块与多处理有类似的问题?

python tkinter multiprocessing

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

Cython numpy数组索引

我正在尝试使用cython加快一些python代码的速度,并且我在使用cython的-a选项来查看可以在哪些方面进行改进。我的理解是,在生成的html文件中,突出显示的行是调用python函数的行-正确吗?

在下面的琐碎函数中,我arr使用缓冲区语法声明了numpy数组参数。我认为这允许索引操作仅在C语言中进行而不必调用python函数。但是,cython -a(版本0.15)突出显示了我设置的元素值的行arr,尽管不是我读取其元素之一的行。为什么会这样?有没有更有效的方式访问numpy数组元素?

import numpy
cimport numpy

def foo(numpy.ndarray[double, ndim=1] arr not None):
    cdef int i
    cdef double elem
    for i in xrange(10):
      elem = arr[i]          #not highlighted
      arr[i] = 1.0 + elem    #highlighted
Run Code Online (Sandbox Code Playgroud)

编辑:此外,mode缓冲区参数如何与numpy交互?假设我没有改变order的参数numpy.array从默认,是它总是安全使用mode='c'?这实际上会对性能产生影响吗?

在delnan的评论之后进行EDIT:arr[i] += 1也被突出显示(这就是为什么我首先将其拆分,以查看导致问题的操作的哪一部分)。如果我关闭边界检查以简化操作(这与突出显示的内容没有区别),则生成的c代码为:

  /* "ct.pyx":11
 *   cdef int i
 *   cdef double elem
 *   for i in xrange(10):             # <<<<<<<<<<<<<<
 *     elem = arr[i]
 *     arr[i] = …
Run Code Online (Sandbox Code Playgroud)

python arrays indexing numpy cython

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

Python 3中的有序类

我正在尝试使用PEP 3115中描述的"有序类" (即,可以按声明的顺序访问其成员的类).给出的实现是

# The custom dictionary
class member_table(dict):
    def __init__(self):
        self.member_names = []

    def __setitem__(self, key, value):
        # if the key is not already defined, add to the
        # list of keys.
        if key not in self:
            self.member_names.append(key)

        # Call superclass
        dict.__setitem__(self, key, value)

# The metaclass
class OrderedClass(type):

    # The prepare function
    @classmethod
    def __prepare__(metacls, name, bases): # No keywords in this case
        return member_table()

    # The metaclass invocation
    def __new__(cls, name, bases, classdict):
        # Note …
Run Code Online (Sandbox Code Playgroud)

python metaclass prepare python-3.x

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

Python:等效于使用sys.stdin的输入

我想测试一些直接使用printand input函数的(python 3)代码。据我了解,最简单的方法是依赖注入:修改代码,使其将输入和输出流作为参数,默认情况下使用sys.stdinsys.stdout,并在测试过程中传入模拟对象。很明显,如何处理print呼叫:

print(text)
#replaced with...
print(text, file=output_stream)
Run Code Online (Sandbox Code Playgroud)

但是,input没有输入和输出流的参数。以下代码是否正确地重现其行为?

text = input(prompt)
#replaced with...
print(prompt, file=output_stream, end='')
text = input_stream.readline()[:-1]
Run Code Online (Sandbox Code Playgroud)

我看过了的实现input,它做了很多魔术,调用sys.stdin.fileno和检查sys.stdin.encodingsys.stdin.errors而不是调用任何read*方法-我不知道从哪里开始模拟这些方法。

python stdin dependency-injection mocking python-3.x

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