Как у вас сейчас, sum
и subtract
действительно методы экземпляра.
>>> foo_obj = object.__new__(foo) # This will actually create a foo object to demonstrate
>>> foo_obj.sum
<bound method foo.sum of <__main__.foo object at 0x0000000000000000>>
>>> type(foo_obj.sum)
<class 'method'>
Но это только потому, что когда вы обращаетесь к ним через экземпляр, Python динамически создает метод (в основном просто привязывает первый аргумент к объекту, обычно self
)
Но вы можете получить доступ к упакованной функции через класс:
>>> foo_obj.sum.__func__
<function foo.sum at 0x0000000000000001>
>>> foo.sum
<function foo.sum at 0x0000000000000001>
>>> foo_obj.sum.__func__ is foo.sum
True
Так что в вашей функции __new__
она не будет привязывать первый аргумент, и они вызывают базовую функцию вместо того, чтобы делать их методом экземпляра.
Чтобы исправить предупреждения, вы можете сделать их classmethod
с или staticmethod
с. Но, как правило, плохая практика - не возвращать объект, который является экземпляром класса из __new__
. Если вы действительно хотите использовать ООП, подкласс int
или создайте оболочку, чтобы вы могли иметь:
>>> class Foo:
__slots__ = 'value',
def __init__(self, a, b, c, add=True):
self.value = self.sum(a, b, c) if add else self.subtract(a, b, c)
@staticmethod
def sum(a, b, c):
return a + b + c
@staticmethod
def subtract(a, b, c):
return c - b - a
>>> foo = Foo(1, 2, 3, True)
>>> foo
<__main__.foo object at 0x0000000000000002>
>>> foo.value
6
или
>>> class Foo(int):
__slots__ = ()
def __new__(cls, a, b, c, add=True):
value = cls.sum(a, b, c) if add else cls.subtract(a, b, c)
return super().__new__(cls, value)
@staticmethod
def sum(a, b, c):
return a + b + c
@staticmethod
def subtract(a, b, c):
return c - b - a
>>> foo = Foo(1, 2, 3, True)
>>> foo
6
>>> type(foo)
<class '__main__.Foo'>