2

__init__是否可以在该描述符的函数期间访问描述符内的“所有者”类,而无需像本例中那样手动传递它?

class FooDescriptor(object):
    def __init__(self, owner):
        #do things to owner here
        setattr(owner, 'bar_attribute', 'bar_value')


class BarClass(object):
    foo_attribute = FooDescriptor(owner=BarClass)
4

2 回答 2

4

做这样的事情的一种方法是使用元类。只要确保它真的是你想要的,如果你不明白它是如何工作的,不要盲目复制。

class Descriptor(object):
    pass

class Meta(type):
    def __new__(cls, name, bases, attrs):
        obj = type.__new__(cls, name, bases, attrs)
        # obj is now a type instance

        # this loop looks for Descriptor subclasses
        # and instantiates them, passing the type as the first argument
        for name, attr in attrs.iteritems():
            if isinstance(attr, type) and issubclass(attr, Descriptor):
                setattr(obj, name, attr(obj))

        return obj

class FooDescriptor(Descriptor):
    def __init__(self, owner):
        owner.foo = 42

class BarClass(object):
    __metaclass__ = Meta
    foo_attribute = FooDescriptor # will be instantiated by the metaclass

print BarClass.foo

如果您需要传递额外的参数,您可以使用例如一个元组来(class, args)代替类,或者制作FooDescriptor一个装饰器,该装饰器将返回一个在ctor 中只接受一个参数的类。

于 2011-05-21T19:09:06.833 回答
4

从 Python 3.6 开始,您可以使用__set_name__特殊方法:

class FooDescriptor(object):
    def __set_name__(self, owner, name):
        owner.foo = 42

class BarClass(object):
    foo_attribute = FooDescriptor()

# foo_attribute.__set_name__(BarClass, "foo_attribute") called after class definition

__set_name__在类创建后立即在类中的所有描述符上自动调用。有关详细信息,请参阅PEP 487 。

于 2019-06-22T05:50:12.210 回答