V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
JhOOOn
V2EX  ›  Python

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

  •  
  •   JhOOOn · 2016-09-08 10:31:59 +08:00 · 4485 次点击
    这是一个创建于 2996 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如:

    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 内哪个好?

    谢。

    9 条回复    2016-09-09 01:02:46 +08:00
    phx13ye
        1
    phx13ye  
       2016-09-08 10:35:14 +08:00
    是的,还可以用 with
    scipio
        2
    scipio  
       2016-09-08 11:34:24 +08:00
    如果是数据库连接这样的,建议用 with 。
    lcj2class
        3
    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
        4
    suueyoung  
       2016-09-08 13:57:38 +08:00
    所以没有 with statement 的包, 我一般都不喜欢.

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

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

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

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

    @JhOOOn lock 不抛异常,我还是拿 open 和 close 说吧。如果 f=open(..)抛了异常,那就不会返回任何东西给 f , f 要么未初始化,要么是上一次的值。把它放进 try 里面,控制流会跳到 finally 中的 f.close()。关闭一个没打开(或已经关闭)的文件就说不通了。
    lcj2class
        8
    lcj2class  
       2016-09-08 22:55:03 +08:00
    想了想,用 else 的方式也不是很好,还是用 f1 的方式好些。具体可以参考: http://stackoverflow.com/a/2837877/2163429
    TaMud
        9
    TaMud  
       2016-09-09 01:02:46 +08:00
    if conn is not None:
    conn.close()
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1004 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:05 · PVG 04:05 · LAX 12:05 · JFK 15:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.