Reputation: 220
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.
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)
Upvotes: 2
Views: 389
Reputation: 71424
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
Upvotes: 2