我有一个简单的问题.不知怎的,我无法找到明确的答案.
有多少是WITH RECURSIVE语法PostgreSQL的优化?我的意思是:它仅仅是一系列非递归查询的语法糖,或者它是一个单一的语句,尽管其复杂的语义已经作为一个整体进行了优化.一个后续问题 - 关于优化这种语法的可能性有多大?当然,非常欢迎有关此事的一些具体数据.
我习惯(被宠坏了?)python的SQLite接口来处理SQL数据库.python的SQLite API中的一个很好的特性是"上下文管理器",即python的with声明.我通常以下列方式执行查询:
import as sqlite
with sqlite.connect(db_filename) as conn:
query = "INSERT OR IGNORE INTO shapes VALUES (?,?);"
results = conn.execute(query, ("ID1","triangle"))
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,如果我的查询修改了数据库并且我忘记运行conn.commit(),则上下文管理器在退出with语句时自动为我运行它.它还可以很好地处理异常:如果在我提交任何内容之前发生异常,则回滚数据库.
我现在正在使用MySQLdb界面,它似乎不支持开箱即用的类似上下文管理器.我如何创建自己的?还有一个相关的问题在这里,但它并没有提供一个完整的解决方案.
我试图理解这些与逐行处理打开文件的方式之间的权衡/差异
with open('data.txt') as inf:
for line in inf:
#etc
Run Code Online (Sandbox Code Playgroud)
VS
for line in open('data.txt'):
# etc
Run Code Online (Sandbox Code Playgroud)
我理解使用with确保在退出"with-block"(套件?)(或者反对异常)时文件被关闭.with自从我在这里学到它以来,我一直在使用.
重新for-loop:来自各地的净等搜索,似乎无论是当文件被关闭for-loop退出取决于具体的实现?我找不到任何关于这个结构如何处理异常的信息.有人知道吗?
如果我对上述任何事情都有误,我会欣赏更正,否则是否有理由使用该for结构
with?(假设你有一个选择,即不受Python版本的限制)
我明白那个
__enter__并__exit__用于实现上下文管理器.
如果with语句中发生异常,则将异常的类型,值和回溯传递给该__exit__方法.
__exit__ 可以处理异常:
True:正常处理异常.with语句引发异常我遇到了以下__exit__方法.return语句是多余的吗?
def __exit__(self, type, value, traceback):
self.close()
return type == None
Run Code Online (Sandbox Code Playgroud)
因为在我看来,
type自然会None,所以__exit__返回true.什么都没有提出来.type则将其设置为实际的异常类型,因此__exit__返回false.异常是按原样引发的.好像我不明白 - 蟒蛇with声明.
考虑这个课程:
class test(object):
def __enter__(self): pass
def __exit__(self, *ignored): pass
Run Code Online (Sandbox Code Playgroud)
现在,当使用它时with,就像在
with test() as michael:
print repr(michael)
Run Code Online (Sandbox Code Playgroud)
我希望有一些输出像<test instance at memore blah>.但是我没有.
这里有什么问题吗?任何建议都会有帮助.
(我使用的是Python 2.6.6.)
编辑:
感谢
ephement指向我的文档.该__enter__方法应阅读
def __enter__(self): return self
Run Code Online (Sandbox Code Playgroud) 为什么这不起作用:
class X:
var1 = 1
def __enter__(self): pass
def __exit__(self, type, value, traceback): pass
with X() as z:
print z.var1
Run Code Online (Sandbox Code Playgroud)
我明白了:
print z.var1
AttributeError: 'NoneType' object has no attribute 'var1'
Run Code Online (Sandbox Code Playgroud) 而不是这个:
FILE = open(f)
do_something(FILE)
FILE.close()
Run Code Online (Sandbox Code Playgroud)
最好使用它:
with open(f) as FILE:
do_something(FILE)
Run Code Online (Sandbox Code Playgroud)
如果我有这样的东西怎么办?
if f is not None:
FILE = open(f)
else:
FILE = None
do_something(FILE)
if FILE is not None:
FILE.close()
Run Code Online (Sandbox Code Playgroud)
当do_something也有一个"如果文件是无"的条款,而且还做一些有用的事情在这种情况下-我不希望只是跳过do_something如果FILE是无.
是否有一种合理的方式将其转换为/作为形式?或者我只是想以错误的方式解决可选文件问题?
我很好奇是否认为安全或良好的做法依赖于python的...作为声明.例如,打开文件时:
with open("myfile","w") as myFile:
#do something
Run Code Online (Sandbox Code Playgroud)
所以在这个例子中我忽略了显式调用myFile.close()但是我可以假设当python with...as通过调用objects __exit__()方法退出语句时调用它.依赖于此是好的做法/安全还是总是明确地打电话会更好file.close()
我正在尝试编写支持以下语义的代码:
with scope('action_name') as s:
do_something()
...
do_some_other_stuff()
Run Code Online (Sandbox Code Playgroud)
范围以及(设置,清理)应该决定是否应该运行此部分.
例如,如果用户将程序配置为绕过'action_name',则在评估Scope()之后,将执行do_some_other_stuff()而不首先调用do_something().
我尝试使用此上下文管理器执行此操作:
@contextmanager
def scope(action):
if action != 'bypass':
yield
Run Code Online (Sandbox Code Playgroud)
但有RuntimeError: generator didn't yield例外(时action为'bypass').
我正在寻找一种方法来支持这一点,而不会回到更详细的可选实现:
with scope('action_name') as s:
if s.should_run():
do_something()
...
do_some_other_stuff()
Run Code Online (Sandbox Code Playgroud)
有谁知道我怎么能做到这一点?
谢谢!
PS我正在使用python2.7
编辑:
解决方案不一定要依赖with语句.没有它,我只是不知道如何表达它.从本质上讲,我想要一种上下文形式的东西(支持设置和自动清理,与所包含的逻辑无关),并允许基于传递给设置方法并在配置中选择的参数进行条件执行.
我还考虑过使用装饰器的可能解决方案.例:
@scope('action_name') # if 'action_name' in allowed actions, do:
# setup()
# do_action_name()
# cleanup()
# otherwise return
def do_action_name()
do_something()
Run Code Online (Sandbox Code Playgroud)
但我不想基于这些范围强制执行太多的内部结构(即,代码如何划分为函数).
有人有一些创意吗?
这是一个问题的延续使用Python'with'语句捕获异常.
我是新手,我在GNU/linux上使用Python 3.2测试了以下代码.
在上述问题中,提出了类似于此的内容,以便从"with"语句中捕获异常:
try:
with open('foo.txt', 'a'):
#
# some_code
#
except IOError:
print('error')
Run Code Online (Sandbox Code Playgroud)
这让我想知道:如果some_code引发IOError而没有捕获它会发生什么?它显然被外部的"除外"声明所吸引,但这可能不是我真正想要的.
你可以说好,只需用另一个try-except包装some_code,依此类推,但我知道异常可以来自任何地方,并且不可能保护每一段代码.
总而言之,我只是想打印'错误',当且仅当open('foo.txt','a')引发异常时,所以我在这里问为什么以下代码不是标准的建议方式这样做:
try:
f = open('foo.txt', 'a')
except IOError:
print('error')
with f:
#
# some_code
#
#EDIT: 'else' statement is missing, see Pythoni's answer
Run Code Online (Sandbox Code Playgroud)
谢谢!
with-statement ×10
python ×9
file-io ×2
as-keyword ×1
database ×1
exception ×1
for-loop ×1
mysql ×1
postgresql ×1