是否可以在该描述符的__init__
函数期间访问描述符内的“owner”类,而不是像本例中那样手动传递它?
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)
答案 0 :(得分: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中只接受一个参数的类。
答案 1 :(得分:1)
从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。