每个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(版本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) 我在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 3.2.2中),
def f():
raise Exception
x = f()
Run Code Online (Sandbox Code Playgroud)
然后它似乎没有x被触及 - 它要么保持未定义,要么保留它以前的任何值.只要赋值的右侧抛出异常,这种行为是否得到保证?我意识到这是一个非常基本的问题,但我找不到有关分配工作原理的详细信息.更一般地说,在与任务相关的任何事情发生之前,是否总是评估整个右侧?在使用setattr,分配列表元素或使用元组解包(即类似的东西x, y = y, f())时,这是否正确?
我有一个昂贵的函数,它接收并返回少量数据(一些整数和浮点数).我已经记住了这个功能,但我想让备忘录持久化.已经有几个与此相关的线程,但我不确定某些建议方法的潜在问题,我有一些相当具体的要求:
multiprocessing和来自不同的python脚本)该主题讨论了该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) 假设我已经定义了一个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有.
在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.我意识到如果我将变量及其名称都传递给函数,这样做是微不足道的,但是在调试时我会使用这样的函数,重复总是会让我感到恼火.
我一直在尝试使用一些代码并行化,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),这似乎在提交的所有作业后,始终悬挂-这似乎发生每当提交的作业数量比工人的数量.如果我ProcessPoolExecutor用ThreadPoolExecutor它替换它完美无瑕.
作为调查的尝试,我给每个未来一个回调打印值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要打印'错误'的价值 …
我知道如何使用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()但没有效果的代码.
另外,请告诉我上面的代码是否有任何不理想 - 我还没有真正掌握所有这些图形,画布和轴对象的功能.
以下代码挂起而没有在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在我需要它的地方进行本地导入(这看起来像坏样式)之外,还有其他解决方法吗?是否有任何其他模块与多处理有类似的问题?
我正在尝试使用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) 我正在尝试使用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) 我想测试一些直接使用printand input函数的(python 3)代码。据我了解,最简单的方法是依赖注入:修改代码,使其将输入和输出流作为参数,默认情况下使用sys.stdin和sys.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.encoding,sys.stdin.errors而不是调用任何read*方法-我不知道从哪里开始模拟这些方法。
python ×13
arrays ×2
indexing ×2
metaclass ×2
numpy ×2
python-3.x ×2
tkinter ×2
class ×1
concurrency ×1
cython ×1
exception ×1
file-locking ×1
matplotlib ×1
memoization ×1
mocking ×1
persistence ×1
pickle ×1
prepare ×1
recursion ×1
reflection ×1
stdin ×1
variables ×1