gpt4 book ai didi

python - 使类中的函数只能在不调用类的情况下访问

转载 作者:行者123 更新时间:2023-12-02 18:32:34 24 4
gpt4 key购买 nike

假设我有这门课:

class A:
def __init__(self, a):
self.a = a
@classmethod
def foo(self):
return 'hello world!'

我使用@classmethod,这样我就可以直接调用函数而不需要调用类:

>>> A.foo()
'hello world!'
>>>

但现在我想知道,因为我仍然可以通过调用类来访问它:

>>> A(1).foo()
'hello world!'
>>>

如果从被调用的类调用函数foo,我是否能够使其引发错误。并且只让它被调用而不调用类,如A.foo()

所以如果我这样做:

A(1).foo()

它应该给出一个错误。

最佳答案

如何查找/绑定(bind)classmethodstaticmethod以及实际上的普通方法的功能是通过descriptors实现的。 。同样,可以定义一个描述符来禁止在实例上查找/绑定(bind)。

此类描述符的简单实现会检查是否通过实例查找它,并在这种情况下引发错误:

class NoInstanceMethod:
"""Descriptor to forbid that other descriptors can be looked up on an instance"""
def __init__(self, descr, name=None):
self.descr = descr
self.name = name

def __set_name__(self, owner, name):
self.name = name

def __get__(self, instance, owner):
# enforce the instance cannot look up the attribute at all
if instance is not None:
raise AttributeError(f"{type(instance).__name__!r} has no attribute {self.name!r}")
# invoke any descriptor we are wrapping
return self.descr.__get__(instance, owner)

这可以应用于其他描述符之上,以防止在实例上查找它们。值得注意的是,它可以与 classmethodstaticmethod 结合使用,以防止在实例上使用它们:

class A:
def __init__(self, a):
self.a = a
@NoInstanceMethod
@classmethod
def foo(cls):
return 'hello world!'


A.foo() # Stdout: hello world!
A(1).foo() # AttributeError: 'A' object has no attribute 'foo'

上面的 NoInstanceMethod 是“天真的”,因为它不负责将 __get__ 之外的描述符调用传播到其包装的描述符。例如,可以传播 __set_name__ 调用以允许包装的描述符知道其名称。

由于描述符可以自由(不)实现任何描述符方法,因此可以支持这一点,但需要适当的错误处理。扩展 NoInstanceMethod 以支持实践中需要的任何描述符方法。

关于python - 使类中的函数只能在不调用类的情况下访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69249450/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com