@property的asigning是如何工作的?(将getter分配给另一个变量。)

2024-04-26 10:24:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的代码:

class Debug(object):
  ...

  @property
  def ThreadAwareLogger(self):
    if not self.logger_instance_for_current_thread:
      self.logger_instance_for_current_thread=self.cloneMainLogger()
    return self.logger_instance_for_current_thread

  def cloneMainLogger(self):
    return logger_instance_for_current_thread

class SomeOtherClass(object):

  def __init__(self):
    ...
    self.logger=debug.ThreadAwareLogger

  def otherMethod(self):
    ...
    self.logger.info("Message")

问题是赋值self.logger=debug.ThreadAwareLogger。我不确定self.logger的内容。我希望它是整个getter,并且每次在SomeOtherClass中使用self.logger时都要执行getter。但是我很抱歉在self.logger中存储的只是getter logger_instance_for_current_thread的结果。这意味着记录在分配时处于活动状态的线程。当我调用self.logger.info("Message")时,这个记录器不一定是正确的。在

如何在每次调用self.logger.info("Message")时执行getterThreadAwareLogger?在

旁注: 为什么我真的需要快捷方式self.logger? 当我决定用AdvancedThreadAwareLogger替换ThreadAwareLogger时,我只更改一个赋值,而不是self.logger.info("Message")的数千个调用。另外,otherMethod不关心将使用哪个记录器。在

编辑:

getter的赋值工作方式如@unutbu的答案所述。但是分配getter会引起一个我以前没有想到的问题。在

ThreadAwareLogger我实际上调用了方法cloneMainLogger。现在的召唤其他类记录器以异常结尾:AttributeError:“SomeOtherClass”对象没有属性“cloneMainLogger”。在

到目前为止,我用一个小黑客绕过了这个问题。SomeOtherClass实际上有一个Debug实例。所以我在ThreadAwareLogger内部调用debug.cloneMainLogger(),而不是self.cloneMainLogger()。这个程序现在可以用了,但我认为它很肮脏。在

编辑2:

如果我在一个方法中添加self.comptreeLogger=Debug.ThreaAwareLogger行;例如cloneMainLogger我将得到AttributeError:“property”对象没有属性“debug”。 结论:我仍然不明白解决办法。在


Tags: instancedebugselfinfomessagefordefcurrent
3条回答
import logging
import random

class Debug(object):
    @property
    def ThreadAwareLogger(self):
        loggers = [logging.getLogger('abc'),logging.getLogger('def')]
        return self.anotherDebugMethod(loggers)
    def anotherDebugMethod(self,loggers):
        return random.choice(loggers)
class SomeOtherClass(object):
    def __init__(self):
        self.debug=Debug()
    @property
    def logger(self):
        return self.debug.ThreadAwareLogger
    def otherMethod(self):
        self.logger.info('Message')

if __name__=='__main__':
    logging.basicConfig(level=logging.DEBUG)    
    x=SomeOtherClass()
    for i in range(5):
        x.otherMethod()

产出如下:

^{pr2}$

请注意,abcdef中的更改表明,Debug.ThreadAwareLogger函数每次都被调用。在

self.logger将引用属性ThreadAwareLogger返回的内容,而不是属性本身。在

获得整个财产的一种方法是制造另一种财产:

class SomeOtherClass:

    @property
    def logger(self):
        return self.debug.ThreadAwareLogger

也许还有其他的方法。在

相关问题 更多 >