首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从with语句返回有趣的值?

如何从with语句返回有趣的值?
EN

Stack Overflow用户
提问于 2009-05-18 13:20:15
回答 3查看 9.3K关注 0票数 8

有比使用globals从上下文管理器获取有趣的值更好的方法吗?

代码语言:javascript
复制
@contextmanager
def transaction():
    global successCount
    global errorCount
    try:
        yield
    except:
        storage.store.rollback()
        errorCount += 1
    else:
        storage.store.commit()
        successCount += 1

其他可能性:

  • 单子

将globals...

  • tuple作为上下文管理器的参数

使函数更特定于将特定属性作为上下文管理器参数的问题reusable

  • instance。

与元组问题相同,但更易读懂的

  • 会在保存值的上下文管理器的末尾引发异常。

真是个坏主意

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-05-18 13:31:38

请参阅http://docs.python.org/reference/datamodel.html#context-managers

创建一个类,它保存成功和错误计数,并实现__enter____exit__方法。

票数 9
EN

Stack Overflow用户

发布于 2009-05-18 13:49:53

我仍然认为您应该创建一个类来保存错误/成功计数,正如我在您的last question中所说的那样。我猜你有自己的课,所以在里面加上这样的内容:

代码语言:javascript
复制
class transaction:
    def __init__(self):
        self.errorCount = 0
        self.successCount = 0  

    def __enter__(*args):
        pass  

    def __exit__(self, type, value, traceback):
        if type:
            storage.store.rollback()
            self.errorCount += 1
        else:
            storage.store.commit()
            self.successCount += 1

(如果在调用type时没有异常,则contextmanager为None )

然后您可能已经在某个地方使用了它,它将调用contextmanager并运行您的__exit__()代码。编辑:正如Eli评论的那样,只在您想要重置coutner时才创建一个新的事务实例。

代码语言:javascript
复制
t = transaction()
for q in queries:
    with t:
        t.execute(q)
票数 5
EN

Stack Overflow用户

发布于 2009-05-18 14:21:02

“元组作为上下文管理器的参数。

使该函数更特定于/less可重用的问题“

假。

这使得上下文管理器保留状态。

如果您没有实现更多的内容,那么它将是可重用的。

但是,实际上不能使用元组,因为它是不可变的。你需要一些易变的收藏。字典和类的定义浮现在脑海中。

因此,建议的实施如下

将特定属性作为上下文管理器参数的实例

只需使用两个属性的简单类定义即可。但是,您的事务状态是有状态的,您需要在某个地方保留状态。

代码语言:javascript
复制
class Counters(dict):
    SUCCEED= 0
    FAIL= 1
    def __init__( self ):
        self[ self.SUCCEED ]= 0
        self[ self.FAIL ]= 0 
    def increment( self, status ):
        self[status] += 1

class Transaction(object):
    def __init__( self, worker, counters ):
        self.worker= worker
        self.counters= counters
    def __enter__( self ):
        self.counters.status= None
    def process( self, *args, **kw ):
        status= self.worker.execute( *args, **kw )
        self.counters.increment( status )
    def __exit__( self ):
        pass

counts= Counters()
for q in queryList:
    with Transaction(execQuery,counts) as t:
        t.process( q )
print counts
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/877709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档