我可以得到“所有者”的参考吗?描述符的 __init__ 方法期间的类?

发布于 2024-11-08 13:08:57 字数 308 浏览 0 评论 0原文

是否可以在描述符的 __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)

Is it possible to access the 'owner' class inside a descriptor during the __init__ function of that descriptor, without passing it in manually as in this example?

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)

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

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

发布评论

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

评论(2

夜巴黎 2024-11-15 13:08:57

执行此类操作的一种方法是使用元类。只要确保它确实是你想要的,如果你不明白它是如何工作的,不要盲目复制。

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 成为一个装饰器,它将返回构造函数中只接受一个参数的类。

One way to do something like that is with a metaclass. Just make sure it's really what you want, and don't just copy blindly if you don't understand how it works.

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

If you need to pass additional arguments, you could use e.g. a tuple of (class, args) in the place of the class, or make FooDescriptor a decorator that would return a class that takes only one argument in the ctor.

黎夕旧梦 2024-11-15 13:08:57

从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

Since Python 3.6, you can use the __set_name__ special method:

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__ is automatically called on all descriptors in a class immediately after the class is created.
See PEP 487 for more details.

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