【问题标题】:Descriptor that auto-detects the name of another attribute passed to it?自动检测传递给它的另一个属性的名称的描述符?
【发布时间】:2010-10-05 20:31:53
【问题描述】:

描述符能否自动检测传递给它的对象的名称?

class MyDecorator( object ):
    def __init__(self, wrapped):
        # Detect that wrapped's name is 'some_attr' here
        pass

class SomeClass( object ):
    some_attr = dict()
    wrapper = MyDecorator( some_attr )

【问题讨论】:

    标签: python metaprogramming descriptor


    【解决方案1】:

    不,不是真的。您可以通过调用框架的自省来破解某些东西,但这不是一个好的——或健壮的——解决方案。 (如果 SomeClass 有两个描述符,some_attr=MyDecorator()someother_attr=some_attr,你会怎么做??)

    最好是明确的:

    def mydecorator(attr):
        class MyDecorator( object ):
            def __get__(self,inst,instcls):
                print(attr)
        return MyDecorator()
    
    class SomeClass( object ):
        some_attr = mydecorator('some_attr')
        someother_attr = mydecorator('someother_attr')    
    
    s=SomeClass()
    s.some_attr
    # some_attr
    
    s.someother_attr
    # someother_attr
    

    【讨论】:

    • 对不起 - 我原来的帖子错误地询问了属性本身的名称,实际上我想要传递给它的东西的名称。当您发布时正在编辑 Q。 :s
    • 与其传递对象some_attr,不如传递字符串名称'some_attr'。使用getattr 从字符串名称到对象很容易。从对象 some_attr 到它的可能的许多字符串变量名称之一要麻烦得多。
    【解决方案2】:

    (为后代回答我自己的问题。)

    这是迄今为止我想出的最好的:

    class MyDecorator( object ):                                               
        def __init__(self, wrapped):                                           
            import inspect                                                     
            for name, obj in inspect.stack(2)[1][0].f_locals.iteritems():    
                if wrapped is obj:                                            
                    print "wrapped attribute is called", name
                    break                                                      
            else:                                                              
                raise RuntimeError("Failed to auto-detect attribute name")     
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-06
      • 2015-07-28
      • 1970-01-01
      • 2021-11-30
      • 1970-01-01
      • 2013-08-14
      • 2014-08-23
      相关资源
      最近更新 更多