Let's say there is a class SomeClass
with function func
which returns int
. How can we implement a similar interface?
class SomeClass:
@overload
@property
def f(self) -> int:
return 1
@overload
def f(self, x: int) -> int:
return x
if __name__ == "__main__":
obj = SomeClass()
print(obj.f) # print 1
print(obj.f(5)) # print 5
Preferably a solution without external modules, but if this is problematic, it is acceptable.
P.S. overload
decorator doesn't exist, this is just an example.
Edit:
Function overloading is given only as an example implementation, but it is not necessary. The main goal is to implement this interface type:
obj = SomeClass()
obj.f # returns 1 (without brackets, works like property)
obj.f(5) # returns 5 (with brackets, works like a normal function)
CodePudding user response:
The core of your problem here is that you want obj.f
to be simultaneously an int
and a function:
print(obj.f) # print 1
print(obj.f(5)) # print 5
This is technically possible by creating a callable int
with the desired behavior, and having your property return that:
class SomeClass:
class TrickyInt(int):
def __new__(cls, val):
return super().__new__(cls, val)
def __call__(self, val):
return self.__class__(val)
@property
def f(self):
return self.TrickyInt(1)
if __name__ == "__main__":
obj = SomeClass()
print(obj.f) # prints 1
print(obj.f(5)) # prints 5
This is a lot of trouble to go to in order to implement a very unintuitive interface, though. I would recommend having this be a regular old method:
class SomeClass:
def f(self, val=1):
return val
if __name__ == "__main__":
obj = SomeClass()
print(obj.f()) # prints 1
print(obj.f(5)) # prints 5