@property 的分配如何进行? (将 getter 分配给另一个变量。)

发布于 2024-12-03 04:45:26 字数 1817 浏览 1 评论 0原文

我有这样的代码:

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") 时,如何让 getter ThreadAwareLogger 执行?

旁注: 为什么我实际上需要快捷方式self.logger? 当我决定用 AdvancedThreadAwareLogger 替换 ThreadAwareLogger 时,我将仅更改一项分配,而不是数千次 self.logger.info("Message") 调用。 otherMethod 也不关心将使用哪个记录器。

编辑:

getter 的分配工作如 @unutbu 的答案中所述。但是吸气剂的分配会导致一个我以前没有想到的问题。

从 ThreadAwareLogger 中,我实际上调用了方法cloneMainLogger。现在 someOtherClass.logger 的调用以异常结束: AttributeError: 'SomeOtherClass' object has no attribute 'cloneMainLogger'。

到目前为止,我通过一个小技巧绕过了这个问题。 SomeOtherClass 实际上有一个 Debug 实例。因此,我在 ThreadAwareLogger 内部调用 debug.cloneMainLogger() 而不是 self.cloneMainLogger() 。该程序现在可以运行,但我认为它真的很脏。

编辑2:

如果我在方法内部添加行self.comptreeLogger=Debug.ThreaAwareLogger;例如 cloneMainLogger 我收到 AttributeError: 'property' 对象没有属性 'debug'。 结论:我仍然不明白解决方案。

I have code like this:

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")

The problematic thing is the assignment self.logger=debug.ThreadAwareLogger. I'm not sure what is gonna be content of self.logger. I want it to be the whole getter and I want to have the getter executed everytime when I use self.logger in SomeOtherClass. But I'm affraid that in self.logger will be stored just the result of the getter logger_instance_for_current_thread. That means logger of the thread which was active at the time of assignment. This logger doesn't have to be the right one when I call self.logger.info("Message").

How to get the getter ThreadAwareLogger executed everytime when I call self.logger.info("Message")?

Sidenote:
Why I actually need the shortcut self.logger?
When I decide to replace ThreadAwareLogger with AdvancedThreadAwareLogger I will change just one assignment instead of thousand calls of self.logger.info("Message"). Also is None of the business of the otherMethod to care about which logger will be used.

Edit:

The assignment of getter works as described in the answer by @unutbu. But assigning of the getter causes an issue I didn't think before.

From the ThreadAwareLogger I actually call method cloneMainLogger. Now the call of someOtherClass.logger ends with exception: AttributeError: 'SomeOtherClass' object has no attribute 'cloneMainLogger'.

So far I bypassed the issue with a small hack. The SomeOtherClass actually has a Debug instance. So I call debug.cloneMainLogger() instead of self.cloneMainLogger() inside of ThreadAwareLogger. The program now works, but I consider it really dirty.

Edit 2:

If I add line self.comptreeLogger=Debug.ThreaAwareLogger inside of a method; e.g. cloneMainLogger I'm getting AttributeError: 'property' object has no attribute 'debug'.
Conclusion: I still don't understand the solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自控 2024-12-10 04:45:26

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

class SomeOtherClass:

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

可能还有其他方法。

One way to get the whole property would be to just make another property:

class SomeOtherClass:

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

There might be other ways, too.

樱花落人离去 2024-12-10 04:45:26
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()

产生如下输出:

INFO:def:Message
INFO:abc:Message
INFO:def:Message
INFO:def:Message
INFO:abc:Message

注意 abcdef 中的变化表明每次都会调用 Debug.ThreadAwareLogger 函数。

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()

yields output like:

INFO:def:Message
INFO:abc:Message
INFO:def:Message
INFO:def:Message
INFO:abc:Message

Notice the changes in abc and def show that the Debug.ThreadAwareLogger function is getting called each time.

人心善变 2024-12-10 04:45:26

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

self.logger will refer to what is returned by the property ThreadAwareLogger, not to the property itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文