我想一次更改几个文件,如果我可以写入所有文件.我想知道我是否能以某种方式将多个开放调用与with语句结合起来:
try:
with open('a', 'w') as a and open('b', 'w') as b:
do_something()
except IOError as e:
print 'Operation failed: %s' % e.strerror
Run Code Online (Sandbox Code Playgroud)
如果那是不可能的,那么这个问题的优雅解决方案会是什么样子?
假设您有三个通过上下文管理器获取的对象,例如A锁,数据库连接和ip套接字.您可以通过以下方式获取它
with lock:
with db_con:
with socket:
#do stuff
Run Code Online (Sandbox Code Playgroud)
但有没有办法在一个街区内完成?就像是
with lock,db_con,socket:
#do stuff
Run Code Online (Sandbox Code Playgroud)
此外,如果有一组具有上下文管理器的未知长度的对象,是否有可能以某种方式做到:
a=[lock1, lock2, lock3, db_con1, socket, db_con2]
with a as res:
#now all objects in array are acquired
Run Code Online (Sandbox Code Playgroud)
如果答案是"不",是不是因为需要这样的功能意味着设计不好,或者我应该建议它?:-P
我们有代码根据运行时参数调用可变数量的上下文管理器:
from contextlib import nested, contextmanager
@contextmanager
def my_context(arg):
print("entering", arg)
try:
yield arg
finally:
print("exiting", arg)
def my_fn(items):
with nested(*(my_context(arg) for arg in items)) as managers:
print("processing under", managers)
my_fn(range(3))
Run Code Online (Sandbox Code Playgroud)
但是,contextlib.nested自Python 2.7以来已弃用:
DeprecationWarning: With-statements now directly support multiple context managers
Run Code Online (Sandbox Code Playgroud)
Python'with '语句中的多个变量的答案表明contextlib.nested存在一些"令人困惑的容易出错的怪癖",但建议使用多管理器with语句的替代方法不适用于可变数量的上下文管理器(并且还会破坏向后兼容性) ).
是否有任何替代品contextlib.nested不被弃用,并且(最好)没有相同的错误?
或者我应该继续使用contextlib.nested并忽略警告?如果是这样,我是否应该计划contextlib.nested在将来的某个时间将其删除?
据我了解,__init__()和__enter__()上下文管理的方法调用一次每个,一个接一个,不留下任何机会之间执行任何其他代码.将它们分成两种方法的目的是什么,我应该将它们放入每种方法中?
编辑:对不起,没注意文档.
编辑2:实际上,我感到困惑的原因是因为我在想@contextmanager装饰师.使用创建的上下文管理器@contextmananger只能使用一次(第一次使用后生成器将耗尽),因此通常使用构造函数内部with语句编写; 如果这是使用with陈述的唯一方法,我的问题就有意义了.当然,实际上,情境管理者比@contextmanager可以创造的更为笼统; 特别是上下文管理器通常可以重用.我希望这次能做对吗?
我正在尝试使用LocalCluster在我的笔记本电脑上使用dask-distributed,但我仍然没有找到一种方法让我的应用程序关闭而不会引发一些警告或触发matplotlib的一些奇怪的迭代(我正在使用tkAgg后端).
例如,如果我按此顺序关闭客户端和群集,则tk无法以适当的方式从内存中删除图像,我收到以下错误:
Traceback (most recent call last):
File "/opt/Python-3.6.0/lib/python3.6/tkinter/__init__.py", line 3501, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Run Code Online (Sandbox Code Playgroud)
例如,以下代码生成此错误:
from time import sleep
import numpy as np
import matplotlib.pyplot as plt
from dask.distributed import Client, LocalCluster
if __name__ == '__main__':
cluster = LocalCluster(
n_workers=2,
processes=True,
threads_per_worker=1
)
client = Client(cluster)
x = np.linspace(0, 1, 100)
y = x * x
plt.plot(x, y)
print('Computation complete! Stopping workers...')
client.close()
sleep(1)
cluster.close()
print('Execution complete!')
Run Code Online (Sandbox Code Playgroud)
该sleep(1)行使问题更容易出现,因为它不会在每次执行时出现. …
我经常错过我尝试使用shutil copyfile复制的文件的最后几个kb.
我做了一些研究,确实看到有人在这里询问类似的东西: python shutil复制函数缺少最后几行
但我正在使用copyfile,它似乎使用了with语句......
with open(src, 'rb') as fsrc:
with open(dst, 'wb') as fdst:
copyfileobj(fsrc, fdst)
Run Code Online (Sandbox Code Playgroud)
所以我很困惑,更多的用户没有这个问题,如果它确实是某种缓冲问题 - 我会认为它更为人所知.
我非常简单地调用copyfile,不要认为我可能做错了什么,基本上按照我认为的标准方式做:
copyfile(target_file_name,dest_file_name)
Run Code Online (Sandbox Code Playgroud)
然而,我每次都错过了最后4kb左右的文件.
我还没有触及在shutil中调用的copyfile函数,它是...
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)
Run Code Online (Sandbox Code Playgroud)
所以我不知所措,但我想我即将学习关于冲洗,缓冲或使用声明的内容,或者......帮助!谢谢
对Anand:Anand,我避免提及那些东西bc我觉得这不是问题,但是因为你问...执行摘要是我从FTP获取文件,检查文件是否与上次不同我保存了一份副本,如果是这样,下载文件并保存副本.它是迂回的意大利面条代码,当我是一个真正纯粹的编程器的新功能时我写的.看起来像:
for filename in ftp.nlst(filematch):
target_file_name = os.path.basename(filename)
with open(target_file_name ,'wb') as fhandle:
try:
ftp.retrbinary('RETR %s' % filename, fhandle.write)
the_files.append(target_file_name)
mtime = modification_date(target_file_name)
mtime_str_for_file = str(mtime)[0:10] + str(mtime)[11:13] + str(mtime)[14:16] …Run Code Online (Sandbox Code Playgroud) 我试图了解 Python 3.10 中带括号的新上下文管理器功能的新增功能(此处新功能的顶部项目)。
我的测试示例是尝试编写:
with (open('file1.txt', 'r') as fin, open('file2.txt', 'w') as fout):
fout.write(fin.read())
Run Code Online (Sandbox Code Playgroud)
一个超级简单的测试,在Python 3.10中完美运行。
我的问题是它在Python 3.9.4中也能完美工作吗?
在 Python 3.8.5 中对此进行测试,看起来它不起作用,从而提高了预期的SyntaxError.
我是否误解了这个更新,因为这个新语法似乎是在 3.9 中引入的?
python ×7
python-3.x ×2
dask ×1
deprecated ×1
file-copying ×1
file-io ×1
python-3.10 ×1
shutil ×1