8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

在 Python 中,如果我在 'with' 块内返回,文件还会关闭吗?

devlin carnate 2月前

114 0

考虑以下内容:with open(path, mode) as f: return [line for line in f if condition] 文件是否会被正确关闭,或者使用 return 是否会以某种方式绕过上下文管理器?

考虑以下:

with open(path, mode) as f:
    return [line for line in f if condition]

文件是否会被正确关闭,或者是否以 return 某种方式绕过 上下文管理器

帖子版权声明 1、本帖标题:在 Python 中,如果我在 'with' 块内返回,文件还会关闭吗?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由devlin carnate在本站《sockets》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 是的,它的作用就像 finally 一个块接着一个 try 块,即它总是执行(当然,除非 python 进程以不寻常的方式终止)。

    的一个示例中也提到了这一点, PEP-343 这是该语句的规范 with

    with locked(myLock):
        # Code here executes with myLock held.  The lock is
        # guaranteed to be released when the block is left (even
        # if via return or by an uncaught exception).
    

    然而值得一提的是, open() 如果不将整个 with 块放入块内 try..except ,而这通常不是人们想要的。

  • 可以将 else 添加到 with 中来解决 try with except 问题。编辑:添加到语言中

  • 我不知道这是否相关,但据我所知,Process.terminate() 是少数(唯一?)不能保证调用 finally 语句的场景之一:\'请注意,退出处理程序和 finally 子句等将不会被执行。\'

  • 有时会使用@RikPoggi os._exit - 它退出 Python 进程而不调用清理处理程序。

  • 也许有点挑衅,但如果我从 with 块中返回一个生成器表达式,那么只要生成器继续产生值,保证是否有效?只要有任何东西引用它,保证是否有效?也就是说,我是否需要使用 del 或为保存生成器对象的变量分配不同的值?

  • @davidA 文件关闭后,引用仍然可以访问;但是,任何尝试使用引用从文件拉取/推送数据的尝试都会产生:ValueError: 对已关闭文件进行 I/O 操作。

  • ovod 2月前 0 只看Ta
    引用 8

    是的。

    def example(path, mode):
        with open(path, mode) as f:
            return [line for line in f if condition]
    

    ..几乎相当于:

    def example(path, mode):
        f = open(path, mode)
    
        try:
            return [line for line in f if condition]
        finally:
            f.close()
    

    更准确地说, __exit__ 上下文管理器中的方法总是在退出块时被调用(无论异常、返回等)。文件对象的 __exit__ 方法只是调用 f.close() (例如 在 CPython 中 )

  • 一个有趣的实验可以展示您从 finally 关键字获得的保证:def test():try:return True; finally:return False。

  • 是的。更一般地, __exit__ 如果 上下文中出现 from ,With 语句上下文管理器 return 的方法

    class MyResource:
        def __enter__(self):
            print('Entering context.')
            return self
    
        def __exit__(self, *exc):
            print('EXITING context.')
    
    def fun():
        with MyResource():
            print('Returning inside with-statement.')
            return
        print('Returning outside with-statement.')
    
    fun()
    

    输出为:

    Entering context.
    Returning inside with-statement.
    EXITING context.
    

    上面的输出确认 __exit__ 尽管很早之前就调用了 return 。因此,上下文管理器没有被绕过。

  • 是的,但在其他情况下可能会有一些副作用,因为它可能应该在 __exit__

    import gzip
    import io
    
    def test(data):
        out = io.BytesIO()
        with gzip.GzipFile(fileobj=out, mode="wb") as f:
            f.write(data)
            return out.getvalue()
    
    def test1(data):
        out = io.BytesIO()
        with gzip.GzipFile(fileobj=out, mode="wb") as f:
            f.write(data)
        return out.getvalue()
    
    print(test(b"test"), test1(b"test"))
    
    # b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff' b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff+I-.\x01\x00\x0c~\x7f\xd8\x04\x00\x00\x00'
    
  • Tajs 2月前 0 只看Ta
    引用 12

    在函数测试中,out.getvalue()发生在__exit__执行之前,所以结果符合预期。

  • 我在 SvelteKit 应用中使用 better-sqlite-3。我有两个表,一个用于客户,一个用于收藏,用户可以将客户设置为收藏,信息保存在 app_users_favorites 中,其中

    我在 SvelteKit 应用中使用 better-sqlite-3。我有两个表,一个用于客户,一个用于收藏,用户可以将客户设置为收藏,信息保存在 中 app_users_favorites ,其中 favorite_id 对应于客户表的键 id(称为“chiave”)列。

    app_users_favorites (
        database_id TEXT,
        user_id TEXT,
        favorite_id TEXT,
    );
    

    这是客户语句,用于无限滚动页面。有一列称为 preferenceito(收藏夹),该列为空,可通过查看收藏夹表来更改,如果 chiave(键)id 在相应的行中,则将 preferenceito 设置为 1 或 0。截至目前,它可以工作,但排序不起作用。如果按 preferenceito 排序,我希望所有收藏夹客户都根据 ASC 或 DESC 出现在列表的顶部或底部。但是,对 favorite 的排序不起作用,对其他每个值的排序都起作用,所以我认为这一定是我对 preferenceito 字段的操作方式。

      getClifor_gen_paginated_search: (
        database_id,
        tipo_clifor,
        searchQuery,
        limit,
        offset,
        orderBy,
        sortDirection,
        user_id
      ) => {
        const validColumns = [
          "rag_soc",
          "cod_clifor",
          "bloccato",
          "preferito",
          "categoria",
          "macrocategoria",
          "sottocategoria",
          "citta",
          "data_ult_ordine",
          "data_ult_doc_ft",
          "data_ult_doc_no_ft",
          "des_raggr1",
          "des_raggr2",
          "des_raggr3",
        ];
        const validDirections = ["ASC", "DESC"];
    
        // Validate orderBy and sortDirection
        if (!validColumns.includes(orderBy)) {
          throw new Error(`Invalid column name: ${orderBy}`);
        }
        if (!validDirections.includes(sortDirection)) {
          throw new Error(`Invalid sort direction: ${sortDirection}`);
        }
    
        // Construct the query
        let orderByClause = "";
    
        if (orderBy === "preferito") {
          orderByClause = `
            ORDER BY preferito ${sortDirection}, rag_soc ASC
            `;
        } else if (orderBy === "bloccato") {
          orderByClause = `
            ORDER BY bloccato ${sortDirection}, preferito DESC, rag_soc ASC
            `;
        } else if (orderBy === "cod_clifor") {
          const reversedSortDirection = sortDirection === "ASC" ? "DESC" : "ASC";
          orderByClause = `
              ORDER BY CAST(cod_clifor AS SIGNED) ${reversedSortDirection}, preferito DESC
              `;
        } else if (orderBy === "rag_soc") {
          const reversedSortDirection = sortDirection === "ASC" ? "DESC" : "ASC";
          orderByClause = `
            ORDER BY rag_soc ${reversedSortDirection}, preferito DESC
            `;
        } else if (
          orderBy === "data_ult_ordine" ||
          orderBy === "data_ult_doc_ft" ||
          orderBy === "data_ult_doc_no_ft"
        ) {
          orderByClause = `
            ORDER BY 
              SUBSTR(${orderBy}, 5, 4) || '-' || SUBSTR(${orderBy}, 3, 2) || '-' || SUBSTR(${orderBy}, 1, 2) ${sortDirection},
              rag_soc ASC
              `;
        }
    
        const query = `
          SELECT 
            clifor_gen.*, 
            CASE 
              WHEN app_users_favorites.favorite_id IS NOT NULL THEN 1
              ELSE 0
            END AS preferito
          FROM 
            clifor_gen
          LEFT JOIN 
            app_users_favorites 
            ON clifor_gen.database_id = app_users_favorites.database_id 
            AND app_users_favorites.user_id = ?
            AND app_users_favorites.favorite_id = clifor_gen.chiave
          WHERE 
            clifor_gen.database_id = ? 
            AND clifor_gen.tipo_clifor = ?
            AND (
              clifor_gen.rag_soc LIKE ? 
              OR clifor_gen.cod_clifor LIKE ? 
              OR clifor_gen.categoria LIKE ? 
              OR clifor_gen.macrocategoria LIKE ? 
              OR clifor_gen.sottocategoria LIKE ? 
              OR clifor_gen.citta LIKE ? 
              OR clifor_gen.des_raggr1 LIKE ? 
              OR clifor_gen.des_raggr2 LIKE ? 
              OR clifor_gen.des_raggr3 LIKE ?
            )
          ${orderByClause}
          LIMIT ? OFFSET ?
        `;
    
        const stmt = db.prepare(query);
    
        return stmt.all(
          user_id,  // user_id for checking if the item is favorited
          database_id,
          tipo_clifor,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          `%${searchQuery}%`,
          limit,
          offset
        );
      },
    };
    
  • 我有以下代码

    我有以下代码

    <html>
    <head>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
    <script src="https://code.jquery.com/jquery-3.7.1.slim.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    
    </head>
    <body>
    <div class="dropdown">
      <button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
        Dropdown button <i class="bi bi-x inside-button"></i>
      </button>
      <ul class="dropdown-menu">
        <li><a class="dropdown-item" href="#">Action</a></li>
        <li><a class="dropdown-item" href="#">Another action</a></li>
        <li><a class="dropdown-item" href="#">Something else here</a></li>
      </ul>
    </div>
    <script>
    $('.inside-button').on('click', function(e) {
        console.log(new Date());
    });
    </script>
    </body>
    </html>

    如您所见,按钮下拉菜单内有一个引导图标,带有单击事件(通过类 inside-button ),此功能的目的是清除下拉菜单的内容。

    问题是单击图标时下拉菜单仍然打开和关闭,单击应该只执行操作而不打开/关闭下拉菜单,我该如何实现呢?

    注意:发布之前我在 中搜索了很多,这是针对 Bootstrap 5 的。

  • Marc 2月前 0 只看Ta
    引用 15

    当您单击时,您可以隐藏下拉菜单 inside-button

    new bootstrap.Dropdown(".dropdown-toggle").hide();
    

    $('.inside-button').on('click', function(e) {
        console.log(new Date());
        new bootstrap.Dropdown(".dropdown-toggle").hide();
    });
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
    <script src="https://code.jquery.com/jquery-3.7.1.slim.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    
    <div class="dropdown">
      <button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
        Dropdown button <i class="bi bi-x inside-button"></i>
      </button>
      <ul class="dropdown-menu">
        <li><a class="dropdown-item" href="#">Action</a></li>
        <li><a class="dropdown-item" href="#">Another action</a></li>
        <li><a class="dropdown-item" href="#">Something else here</a></li>
      </ul>
    </div>
  • myol 2月前 0 只看Ta
    引用 16

    最简单的方法可能是将图标元素移出按钮,这样它就不会触发下拉菜单,并且只能通过内部单击关闭下拉菜单 data-bs-auto-close="inside (缺点是现在下拉菜单无法通过外部单击关闭......)然后使用 css 设置其样式以使其与按钮文本和下拉菜单对齐。

    另一种方法是添加大量 JS 监听器,这将有条件地触发下拉菜单,但这不是一个好的解决方案。

    这是一个简单的例子,

    • p3

    • p4

    • p5

    • p6

    • p7

        <button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="inside>  <span style="  padding-right: 20px;  ">Dropdown button</span></button>  <i class="bi bi-x inside-button" style="  margin-left: -43px;  color: var(--bs-white);

      p8

    演示:

    <html>
    
    <head>
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
      <script src="https://code.jquery.com/jquery-3.7.1.slim.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    
    </head>
    
    <body>
      <div class="dropdown" style="
        display: flex;
        align-items: center;
    ">
        <button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="inside">
        <span style="
        padding-right: 20px;
        ">Dropdown button</span></button>
        <i class="bi bi-x inside-button" style="
        margin-left: -43px;
        color: var(--bs-white);
    
    "></i>
        <ul class="dropdown-menu" style="">
          <li><a class="dropdown-item" href="#">Action</a></li>
          <li><a class="dropdown-item" href="#">Another action</a></li>
          <li><a class="dropdown-item" href="#">Something else here</a></li>
        </ul>
      </div>
      </div>
      <script>
        $('.inside-button').on('click', function(e) {
          console.log(new Date());
        });
      </script>
    </body>
    
    </html>
返回
作者最近主题: