我必须在python中打开一个类似文件的对象(它是通过/ dev /的串行连接),然后关闭它.这在我班上的几种方法中已经完成了好几次.我是如何做的是在构造函数中打开文件,然后在析构函数中关闭它.虽然我得到了奇怪的错误,我认为它与垃圾收集器有关,所以,我仍然不习惯不知道我的对象何时被删除= \
我这样做的原因是因为tcsetattr每次打开它时我都必须使用一堆参数,并且在整个地方做这一切都很烦人.所以我想实现一个内部类来处理所有这些,所以我可以用它来做
with Meter('/dev/ttyS2') as m:
我在网上看,我找不到一个关于如何实现with语法的非常好的答案.我看到它使用__enter__(self)和__exit(self)__方法.但是,我是否必须实现这些方法,我可以使用with语法?或者还有更多吗?
是否有关于如何执行此操作的示例或有关如何在文件对象上实现它的一些文档我可以查看?
我有以下代码:
class Test:
def __init__(self, name):
self.name = name
def __enter__(self):
print(f'entering {self.name}')
def __exit__(self, exctype, excinst, exctb) -> bool:
print(f'exiting {self.name}')
return True
with Test('first') as test:
print(f'in {test.name}')
test = Test('second')
with test:
print(f'in {test.name}')
Run Code Online (Sandbox Code Playgroud)
运行它会产生以下输出:
class Test:
def __init__(self, name):
self.name = name
def __enter__(self):
print(f'entering {self.name}')
def __exit__(self, exctype, excinst, exctb) -> bool:
print(f'exiting {self.name}')
return True
with Test('first') as test:
print(f'in {test.name}')
test = Test('second')
with test:
print(f'in {test.name}')
Run Code Online (Sandbox Code Playgroud)
但我预计它会产生:
entering first
exiting first
entering …Run Code Online (Sandbox Code Playgroud) 我有一些带遗留函数的遗留代码,它将文件名作为参数并处理文件内容.下面是代码的工作传真.
我想要做的是不必使用我生成的一些内容写入磁盘以使用此遗留函数,因此我可以使用StringIO创建对象来代替物理文件名.但是,这不起作用,如下所示.
我认为StringIO是这样的方式.任何人都可以告诉我是否有一种方法可以使用这个遗留函数并在参数中传递一些东西,而不是磁盘上的文件但可以通过遗留函数对待它?遗留函数确实让with上下文管理器对filename参数值进行处理.
我在谷歌遇到的一件事是:http://bugs.python.org/issue1286,但这对我没有帮助......
码
from pprint import pprint
import StringIO
# Legacy Function
def processFile(filename):
with open(filename, 'r') as fh:
return fh.readlines()
# This works
print 'This is the output of FileOnDisk.txt'
pprint(processFile('c:/temp/FileOnDisk.txt'))
print
# This fails
plink_data = StringIO.StringIO('StringIO data.')
print 'This is the error.'
pprint(processFile(plink_data))
Run Code Online (Sandbox Code Playgroud)
产量
这是输出FileOnDisk.txt:
['This file is on disk.\n']
Run Code Online (Sandbox Code Playgroud)
这是错误:
Traceback (most recent call last):
File "C:\temp\test.py", line 20, in …Run Code Online (Sandbox Code Playgroud) 有没有办法在Python 2.7的上下文管理器中创建临时目录?
with tempfile.TemporaryDirectory() as temp_dir:
# modify files in this dir
# here the temporary diretory does not exist any more.
Run Code Online (Sandbox Code Playgroud) 我知道该with声明可以帮助你解决这个问题:
try:
f = open(my_file)
do_stuff_that_fails()
except:
pass
finally:
f.close()
Run Code Online (Sandbox Code Playgroud)
成:
with open(my_file) as f:
do_stuff_that_fails()
Run Code Online (Sandbox Code Playgroud)
但那怎么样更好?您仍然需要处理无法打开文件的情况(比如提示用户告诉他他没有权限),所以实际上你有:
try:
with open(my_file) as f:
do_stuff_that_fails()
except (IOError, OSError, Failure) as e:
do_stuff_when_it_doesnt_work()
Run Code Online (Sandbox Code Playgroud)
这相当于:
try:
f = open(my_file)
do_stuff_that_fails()
except (IOError, OSError, Faillure) as e:
do_stuff_when_it_doesnt_work()
finally:
f.close()
Run Code Online (Sandbox Code Playgroud)
是的,你获得了两行,但是你添加了一个嵌套级别,这使得它更容易阅读.with声明的目的是为了节省两行还是我遗漏了什么?
为此添加一个关键字似乎很多,所以我觉得有一些语法来处理额外的尝试/除了我不知道的.
with在python中创建多行的简洁方法是什么?我想在一个单独的文件中打开几个文件with,但它足够远,我想要它在多行上.像这样:
class Dummy:
def __enter__(self): pass
def __exit__(self, type, value, traceback): pass
with Dummy() as a, Dummy() as b,
Dummy() as c:
pass
Run Code Online (Sandbox Code Playgroud)
不幸的是,那是一个SyntaxError.所以我尝试了这个:
with (Dummy() as a, Dummy() as b,
Dummy() as c):
pass
Run Code Online (Sandbox Code Playgroud)
还有一个语法错误.但是,这有效:
with Dummy() as a, Dummy() as b,\
Dummy() as c:
pass
Run Code Online (Sandbox Code Playgroud)
但是,如果我想发表评论怎么办?这不起作用:
with Dummy() as a, Dummy() as b,\
# my comment explaining why I wanted Dummy() as c\
Dummy() as c:
pass
Run Code Online (Sandbox Code Playgroud)
\s 的位置也没有任何明显的变化.
是否有一种干净的方法来创建with允许在其中发表评论的多行语句?
所以我想做以下事情:
{% if age > 18 %}
{% with patient as p %}
{% else %}
{% with patient.parent as p %}
...
{% endwith %}
{% endif %}
Run Code Online (Sandbox Code Playgroud)
但Django告诉我,我需要另一个{%endwith%}标签.是否有任何方法可以重新排列withs以使其工作,或者语法分析器是否有目的无忧无虑的这种事情?
也许我会以错误的方式解决这个问题.在涉及到这样的事情时,是否有某种最佳实践?
只需从本文中了解语句即可
问题是,我可以通过论证__enter__吗?
我有这样的代码:
class clippy_runner:
def __enter__(self):
self.engine = ExcelConnection(filename = "clippytest\Test.xlsx")
self.db = SQLConnection(param_dict = DATASOURCES[STAGE_RELATIONAL])
self.engine.connect()
self.db.connect()
return self
Run Code Online (Sandbox Code Playgroud)
我想将filename和param_dict作为参数传递给__enter__.那可能吗?
我一直在阅读关于delphi中with关键字的坏事,但在我看来,如果你不过度使用它.它可以使您的代码看起来很简单.
我经常将所有TClientDataSets和TField都放在TDataModules中.所以在我的表单中我有这样的代码
procedure TMyForm.AddButtonClick(Sender: TObject);
begin
with LongNameDataModule do
begin
LongNameTable1.Insert;
LongNameTable1_Field1.Value := "some value";
LongNameTable1_Field2.Value := LongNameTable2_LongNameField1.Value;
LongNameTable1_Field3.Value := LongNameTable3_LongNameField1.Value;
LongNameTable1_Field4.Value := LongNameTable4_LongNameField1.Value;
LongNameTable1.Post;
end
end;
Run Code Online (Sandbox Code Playgroud)
如果没有with关键字,我必须编写这样的代码
procedure TMyForm.AddButtonClick(Sender: TObject);
begin
LongNameDataModule.LongNameTable1.Insert;
LongNameDataModule.LongNameTable1_LongNameField1.Value := "some value";
LongNameDataModule.LongNameTable1_LongNameField2.Value :=
LongNameDataModule.LongNameTable2_LongNameField1.Value;
LongNameDataModule.LongNameTable1_LongNameField3.Value :=
LongNameDataModule.LongNameTable3_LongNameField1.Value;
LongNameDataModule.LongNameTable1_LongNameField4.Value :=
LongNameDataModule.LongNameTable4_LongNameField1.Value;
LongNameDataModule.LongNameTable1.Post;
end;
Run Code Online (Sandbox Code Playgroud)
我认为使用with关键字更容易阅读.
我应该避免使用with关键字吗?
我想with在某些条件下退出声明:
with open(path) as f:
print 'before condition'
if <condition>: break #syntax error!
print 'after condition'
Run Code Online (Sandbox Code Playgroud)
当然,上述方法不起作用.有没有办法做到这一点?(我知道我可以改变这种情况:if not <condition>: print 'after condition'- 任何方式就像上面那样?)
with-statement ×10
python ×8
python-3.x ×2
class ×1
delphi ×1
django ×1
exception ×1
file-io ×1
if-statement ×1
multiline ×1
python-2.7 ×1
python-2.x ×1
temp ×1
templates ×1