In essence, I'm trying to accomplish the below but where bar and baz have the same handle (e.g. just bar) rather than being two differently-named functions.
Definitions
import numpy as np
foo = np.add # For example; real function will be different in every instance
class MyClass(object):
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2
def bar(self):
return foo(self.arg1, self.arg2)
@classmethod
def baz(cls, arg1, arg2):
return foo(arg1, arg2)
Example Usage
a, b = 1, 2
mine = MyClass(a, b)
print(mine.bar())
>>> 3
x, y = 3, 4
print(MyClass.baz(x, y))
>>> 7
I'm trying to do this for intelligibility's sake. The real function names are long with many underscores, and making two slightly differently-named functions (e.g. prepending one function name with a _) for every function to which I want to do this is only going to confuse an already complicated situation.
The function will mostly be used internally, but I'd like the ability to call the function in a static context with ad hoc parameters that might not necessarily match the instance variables of a given object of MyClass (in fact, I would only call it this way if they didn't match). I'm using @classmethod rather than @staticmethod because the real functions use some internal class variables.
I've already tried simply implementing the above with bar for both function names, but as expected, the instance method has been overridden by the class method.
I suppose one awkward solution would be to define
baras:def bar(self, arg1=None, arg2=None): if arg1 is None: arg1 = self.arg1 if arg2 is None: arg2 = self.arg2 return foo(arg1, arg2)and then, if I wanted to call it statically elsewhere, I would need to use:
# Assuming that a specific object of MyClass does not exist yet useless = "not", "used" mine = MyClass(*useless) x, y = 6, 9 print(mine.bar(x, y))I don't really like this because it requires me to call
barfrom a specific object ofMyClass. This is technically not an issue if I already have an instance ofMyClasssomewhere, but I want a class method for a reason:barin this context doesn't depend on any instance variables (though it does on class variables).Another potential solution would be to make a separate class for this function (and others):
class Functions(object): @classmethod def bar(cls, arg1, arg2): return foo(arg1, arg2)and to call it within
MyClassasFunctions.bar(self.arg1, self.arg2)and externally asFunctions.bar(arg1, arg2)I'm not super keen on this either since I'm putting
barand similar functions inMyClassfor a reason: they're relevant toMyClassconceptually.
I saw some answers to similar SO posts that use Descriptors, but I was hoping there might be a more elegant solution.
Any wise Python wizards out here have advice?
You can let
selftake a default argument as well, so that you can distinguish betweenmine.bar()andMyClass.bar(). The price is that the other two arguments must be keyword arguments.