Вы можете настроить класс __getattribute__
, как в ответе Schwobaseggl, но вы также можете использовать пользовательский метакласс.
Когда мы упоминаем «метакласс» в Python, обычно рассматривается переопределение его метода __new__
и выполнение сложных задач во время создания класса (в отличие от времени создания экземпляра). Однако, если вы оставите все специальные dunder (__these__ __methods__
) в стороне, метаклас - это просто класс класса, и все его методы будут видны из самого класса, но не будут видны из экземпляров класса. Это означает, что они не будут отображаться, если один экземпляр «dir», но будет отображаться, когда один «dir» класс - и не будет непосредственно извлечен через экземпляр. (Хотя, конечно, всегда можно сделать self.__class__.method
)
Кроме того, несмотря на обоснованную обливание известности metaclasse сложности, перекрывая __getattribute__
сам может иметь некоторые pitfalls.
В данном конкретном случае classs вы хотите защитить alreayd использовать метакласс - но это конкретное использование, в отличие от «обычного» метакласс использует, может быть свободно компонуем так же, как обычные иерархии классов:
class ClsMethods(BaseModel):
# inherit from `type` if there is no metaclass already
# now, just leave __new__, __init__, __prepare__ , alone
# and write your class methods as ordinary methods:
def update(cls, *args, **kw):
...
def fetch_rows_from(self, ...):
...
class Model(with_metaclass(ClsMethods)):
# This really socks. Do you really still need Py2 support? :-)
...
(Это должно быть очевидно, но воспринимает не нужно объявлять метод в метаклассе, как методы класс: все они являются для методы класса метакласса например, что класс)
И быстрые демо на консоль:
In [37]: class M(type):
...: def secret(cls): print("At class only")
...:
In [38]: class A(metaclass=M):
...: pass
...:
In [39]: A.secret()
At class only
In [40]: A().secret()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-40-06355f714f97> in <module>()
----> 1 A().secret()
AttributeError: 'A' object has no attribute 'secret'
Я не думаю, что вы можете сделать это с помощью «classmethod'. Вам придется написать свой собственный дескриптор, похожий на 'classmethod', который проверяет, привязан ли он к экземпляру и генерирует исключение. – BrenBarn