python 里 finally 需要关闭的操作是放到 try 里还是 try 外?

2016-09-08 10:31:59 +08:00
 JhOOOn

比如:

def f1():
  conn = mysql.conn(host='12')
  try:
    pass
  finally:
    conn.close()
    
def f2():
  try:
    conn = mysql.conn(host='12')
    pass
  finally:
    conn.close()
    
def f3():
  try:
    conn = mysql.conn(host='12')
    pass
  finally:
    if conn:
      conn.close()

注意,这里的 conn 可能会出现错误。

我认为应该像 f3 那样写,

  1. 那么是不是需要在 try 的外面初始化下 conn

  2. 类似的还有多线程编程里获取一个锁,释放一个锁操作, try 外还是 try 内哪个好?

谢。

4336 次点击
所在节点    Python
9 条回复
phx13ye
2016-09-08 10:35:14 +08:00
是的,还可以用 with
scipio
2016-09-08 11:34:24 +08:00
如果是数据库连接这样的,建议用 with 。
lcj2class
2016-09-08 11:49:40 +08:00
connector-python 是这么做的:

```
try:
cnx = mysql.connector.connect(user='scott',
database='testt')
except mysql.connector.Error as err:
print(err)
else:
cnx.close()
```

connect 肯定是在 try 内获取的
suueyoung
2016-09-08 13:57:38 +08:00
所以没有 with statement 的包, 我一般都不喜欢.

说的就是 https://pypi.python.org/pypi/jira
wizardforcel
2016-09-08 14:15:14 +08:00
锁的话必然是 f1 。

实际上 java 的 sync 语句反编译之后你会发现,它 monitor-enter 是在 try 前面, monitor-exit 是在 finally 里面。
JhOOOn
2016-09-08 14:26:08 +08:00
@phx13ye
谢谢

@lcj2class
这里我理解 try 语句里就只有 connection 操作, 其他操作放到 else 中是吗?

@wizardforcel
多谢, 这里为什么锁放在 try 外面呢?不是很理解,如果放在 try 里面会出现什么问题呢?
wizardforcel
2016-09-08 14:54:05 +08:00
@suueyoung 这个貌似可以自己封装一层。。

@JhOOOn lock 不抛异常,我还是拿 open 和 close 说吧。如果 f=open(..)抛了异常,那就不会返回任何东西给 f , f 要么未初始化,要么是上一次的值。把它放进 try 里面,控制流会跳到 finally 中的 f.close()。关闭一个没打开(或已经关闭)的文件就说不通了。
lcj2class
2016-09-08 22:55:03 +08:00
想了想,用 else 的方式也不是很好,还是用 f1 的方式好些。具体可以参考: http://stackoverflow.com/a/2837877/2163429
TaMud
2016-09-09 01:02:46 +08:00
if conn is not None:
conn.close()

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/304747

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX