标签: contextmanager

Pandas DataFrame.to_sql() 不再使用 sqlalchemy 2.0.1 engine.connect() 作为上下文管理器,并且不会抛出任何错误

这段带有pandas 1.5.3sqlalchemy 的 2.0.1代码不再工作,令人惊讶的是,它不会引发任何错误,代码默默地通过:

# python 3.10.6
import pandas as pd # 1.5.3
import psycopg2 # '2.9.5 (dt dec pq3 ext lo64)'
from sqlalchemy import create_engine # 2.0.1


def connector():
    return psycopg2.connect(**DB_PARAMS)

engine = create_engine('postgresql+psycopg2://', creator=connector)

with engine.connect() as connection:
    df.to_sql(
        name='my_table',
        con=connection,
        if_exists='replace',
        index=False,
    )
Run Code Online (Sandbox Code Playgroud)

目前,使用 sqlalchemy,2.0.1我的表不再填充 DataFrame 内容。

而它已正确填充 sqlalchemy version 1.4.45

编辑

显然,当我使用上下文管理器时它会起作用:

connection = engine.connect()

res.to_sql(
    name='my_table',
    con=connection,
    if_exists='replace',
    index=False
)
Out[2]: 133 # <- wondering what …
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy psycopg2 contextmanager pandas

2
推荐指数
1
解决办法
3586
查看次数

Python"with"语句堆积

我倾向于经常使用Python"with"语句.在我将一些文件符号链接或复制到目录后,主要用于清理目录,因为即使python脚本崩溃,任务仍然会执行.以下是我的函数的示例,可以与"with"语句一起使用.

@contextmanager
def use_symlink(orig, dest):
    os.symlink(orig, dest)
    try: 
        yield
    finally:
        os.unlink(link)
Run Code Online (Sandbox Code Playgroud)

我使用这些语句的方式很快就会堆积起来.

#Off to an adventure
with use_symlink(a, b):
    with use_symlink(c, b):
        with use_symlink(d, b):
            with working_dir(dir1):
                #do something
            with working_dir(dir2):
                #do something that creates file dir2_file1, dir2_file2
                with use_symlink(dir2_file1, b):
                   with use_symlink(dir2_file2, b):
                       with working_dir(b):
                           #Do the last thing
#Home safely
Run Code Online (Sandbox Code Playgroud)

是否有更好的方法来执行上述操作与强大的"with"语句相同的简易性和安全性?

python with-statement contextmanager

1
推荐指数
1
解决办法
244
查看次数

Python可迭代和上下文管理器

我想要这样的行为:

with A() as f:
    for x in f:
        do_something(f)
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?

class A:
    def __enter__(self):
        print "Entering context"

    def __iter__(self):
        for x in ["some","list"]:
            yield x

    def __exit__(self):
        print "Deleting context"
Run Code Online (Sandbox Code Playgroud)

python contextmanager

1
推荐指数
1
解决办法
957
查看次数

__del__是不可靠的,但如果我尝试使用上下文管理器,则该对象不会持久存在

我有一个脚本,实例化了许多子对象.当脚本(和这些对象)结束时......对象需要做一些清理(尤其是临时文件关闭和删除).

我一直在阅读如何__del__不可靠 - 但是上下文管理似乎不起作用,子对象不会持久.他们需要四处闲逛(做文件读写等事情)

一个例子:

WRITER.PY

import os

class Writer(object):
    def __init__(self, filename):
        self.filename = filename
        self.open()

    def open(self):
        self.fh = open(self.filename, "w+", 0)

    def write(self, msg):
        print >>self.fh, str(msg)

    def close(self):
        self.fh.close()
        os.remove(self.filename)

    def __enter__(self):
        print "entered"
#         self.open()


    def __exit__(self, type, value, traceback):
        print "__exit__"
        self.close()
Run Code Online (Sandbox Code Playgroud)

MAIN.PY

def myfunc(filename):
    with WRITER.Writer(filename) as writeit:
        # do some stuff
        writeit.write("hallo")
        # do some more stuff
        writeit.write("more results")
        # even more stuff
        writeit.write("goodbye")
Run Code Online (Sandbox Code Playgroud)

但是当我运行时myfunc(),对象一旦完成就会被垃圾收集__init__().它直接从enter到exit并且在with语句之后不执行任何任务.如果我把开放放入__init__ …

python with-statement del resource-cleanup contextmanager

1
推荐指数
1
解决办法
51
查看次数

如何访问上下文管理器的属性?

我想完成以下事情:

class my_context(object):
    def __init__(self):
        self.obj1 = Obj()
        self.obj2 = Obj()
        ...

    def __enter__(self):
        ''' initialize objects '''

    def __exit__(self, type, value, tb):
        ''' uninitialize objects '''
Run Code Online (Sandbox Code Playgroud)

有许多Obj属性是需要关闭/删除/等的资源.我希望使用上下文管理器来设置它们然后摆脱它们.但是我发现我尝试时无法访问属性:

with my_context() as cont:
    cont.obj1  # doesn't work
Run Code Online (Sandbox Code Playgroud)

有没有办法可以访问这些属性?

python contextmanager

1
推荐指数
1
解决办法
223
查看次数

我可以从python上下文管理器中检索__exit__的返回值吗?

我在python中使用上下文管理器。想要从我的__exit__方法中获取一些日志。所以我的代码记录如下:

class MyContextManager:
    def __init__(self, value1, value2)
        self.value1 = value1
        self.value2 = value2

    def __enter__(self)
        # Do some other stuff
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # Do some tear down action, process some data that is 
        # created in __enter__ and log those results
        return my_results

with MyContextManager(value1=my_value1, value2=my_value2) as manager:
     # Do some stuff
Run Code Online (Sandbox Code Playgroud)

因此,如何访问__exit__with块之后(或末尾)返回的my_results 。在该__exit__方法中返回其他True甚至合法吗?

python with-statement contextmanager

1
推荐指数
1
解决办法
978
查看次数

如何在异步循环关闭之前等待对象的__del__完成?

我有一个将在其中包含aiohttp.ClientSession对象的类。

通常当您使用

async with aiohttp.ClientSession() as session:  
   # some code
Run Code Online (Sandbox Code Playgroud)

由于调用了会话的__aexit__方法,因此该会话将关闭。

我无法使用上下文管理器,因为我想在对象的整个生命周期中保持会话的持久性。

这有效:

import asyncio
import aiohttp

class MyAPI:
    def __init__(self):
        self.session = aiohttp.ClientSession()

    def __del__(self):
        # Close connection when this object is destroyed
        print('In __del__ now')
        asyncio.shield(self.session.__aexit__(None, None, None))



async def main():
    api = MyAPI()

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

但是,如果在某些地方引发了异常,则在完成__aexit__方法之前将关闭事件循环。我该如何克服?

堆栈跟踪:

Traceback (most recent call last):
  File "/home/ron/.PyCharm2018.3/config/scratches/async.py", line 19, in <module>
    asyncio.run(main())
  File "/usr/local/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 568, in run_until_complete
    return future.result()
  File "/home/ron/.PyCharm2018.3/config/scratches/async.py", line …
Run Code Online (Sandbox Code Playgroud)

python contextmanager python-asyncio aiohttp

1
推荐指数
2
解决办法
416
查看次数

在multiprocessing.Manager中使用上下文管理员有什么好处?

文档中,Manager与上下文管理器(即with)一起使用,如下所示:

from multiprocessing.managers import BaseManager

class MathsClass:
    def add(self, x, y):
        return x + y
    def mul(self, x, y):
        return x * y

class MyManager(BaseManager):
    pass

MyManager.register('Maths', MathsClass)

if __name__ == '__main__':
    with MyManager() as manager:
        maths = manager.Maths()
        print(maths.add(4, 3))         # prints 7
        print(maths.mul(7, 8))         # prints 56
Run Code Online (Sandbox Code Playgroud)

但是,除了名称空间之外,这样做还有什么好处?对于打开文件流,其好处是显而易见的,因为您不必手动.close()进行连接,但这对Manager有什么作用?如果您不在上下文中使用它,则必须使用什么步骤来确保所有内容均正确关闭?

简而言之,与上述类似,使用以上内容有什么好处:

manager = MyManager()
maths = manager.Maths()
print(maths.add(4, 3))         # prints 7
print(maths.mul(7, 8))         # prints 56
Run Code Online (Sandbox Code Playgroud)

python multiprocessing contextmanager python-3.x

1
推荐指数
1
解决办法
94
查看次数

Python 模拟 psycopg2 连接和光标

我无法模拟 psycopg2 数据库连接和游标,因为我已将其重构为使用游标的上下文管理器。我知道使用上下文管理器时,会调用额外的魔术方法来进行资源设置和清理(__enter____exit__),但即使将其添加到组合中也没有缩小问题的范围。

这是代码:

import os
import psycopg2
import psycopg2.extras

DB_HOST = os.getenv('DB_HOST')     
DB_PORT = os.getenv('DB_PORT')
DB_NAME = os.getenv('DB_NAME')
DB_USER = os.getenv('DB_USER')
DB_PASSWORD = os.getenv('DB_PASSWORD')            
CONN = psycopg2.connect(f'dbname={DB_NAME} user={DB_USER} host={DB_HOST} port={DB_PORT} password={DB_PASSWORD}')

def my_func():
    message = None
    print(CONN)  # Added to debug - this never prints out a magic mock reference

    select_sql = 'SELECT * FROM app.users WHERE name = %s LIMIT 1;'
    with CONN.cursor(cursor_factory = psycopg2.extras.DictCursor) as cursor:
        print(cursor) # Debug - no magic mock …
Run Code Online (Sandbox Code Playgroud)

python unit-testing mocking contextmanager pytest

1
推荐指数
1
解决办法
6415
查看次数

如何在不编写额外代码的情况下使用 Python 将“-”(破折号)作为标准输入读取?

使用 Python 3.5.x,没有比这更高的版本。

/sf/answers/2117818601/是正确的答案,但没有提供内置于 Python 的解决方案,而是需要从头开始编写代码:

我需要一个值为“-”的字符串来表示标准输入,或者它的值是我想要读取的文本文件的路径。我想使用with运算符打开这些文件中的任何一种,而不使用条件逻辑来检查脚本中的“-”。我有一些有用的东西,但它似乎应该是内置在 Python 核心中的东西,而不需要我推出自己的上下文管理器,如下所示:

from contextlib import contextmanager

@contextmanager
def read_text_file_or_stdin(path):
    """Return a file object from stdin if path is '-', else read from path as a text file."""
    if path == '-':
        with open(0) as f:
            yield f
    else:
        with open(path, 'r') as f:
            yield f


# path = '-'  # Means read from stdin
path = '/tmp/paths'  # Means read from a text file given by this value
with read_text_file_or_stdin(path) …
Run Code Online (Sandbox Code Playgroud)

python stdin contextmanager

1
推荐指数
1
解决办法
855
查看次数

如何定义 ContextManager 协议

我尝试使用类型提示来指定实现连接器类(在本例中为代理)时要遵循的 API。

我想指定这样的类应该是上下文管理器

我怎么做?

让我更清楚地重新表述一下:我如何定义Broker类,以便它表明它的具体实现(例如Rabbit类)必须是上下文管理器?

有没有实用的办法呢?我是否必须指定__enter__and__exit__并继承自Protocol

继承就足够了吗ContextManager

顺便问一下,我应该使用@runtimeor@runtime_checkable吗?(我的 VScode linter 似乎在查找 . 中的内容时遇到问题typing。我使用的是 python 3 7.5)

我知道如何使用 ABC 来做到这一点,但我想学习如何使用协议定义来做到这一点(我已经很好地使用了协议定义,但它们不是上下文管理器)。

我不知道如何使用该ContextManager类型。到目前为止我还没能从官方文档中找到好的例子。

目前我想出了

from typing import Protocol, ContextManager, runtime, Dict, List


@runtime
class Broker(ContextManager):
    """
    Basic interface to a broker.
    It must be a context manager
    """

    def publish(self, data: str) -> None:
        """
        Publish data to the topic/queue
        """
        ... …
Run Code Online (Sandbox Code Playgroud)

python type-hinting contextmanager

1
推荐指数
1
解决办法
2147
查看次数

为什么你可以使用open()作为上下文管理器?

从Python的源代码来看open,我认为open这只是一个普通的函数.

为什么我们可以像下面这样使用它?

with open('what_are_context_managers.txt', 'r') as infile:
    for line in infile:
        print('> {}'.format(line))
Run Code Online (Sandbox Code Playgroud)

因为既不是实现__enter__也不是__exit__,也不使用contextlib.contextmanager装饰器.

python contextmanager

0
推荐指数
1
解决办法
469
查看次数