1

I'm trying to make a Python class (call it CLASS) in which there is a main function (call it FUNC) that most users will wish to use.

In this case I would like the user to be able to call the class name without the need to use brackets before the favourite function eg.:

CLASS(B, C) rather than CLASS().FUNC(B, C)

This is purely aesthetic but it means that for users who will use FUNC and not care about the other functions they could explicitly call, they don't need to write the annoying curly brackets.

Here is a simple code example of the kind of class I would create, where the main function (which I've called FUNC for continuity) utilises other functions in the class:

class Example:

    def dummy_operation(self,A):
        return A*2.

    def FUNC(self,B,C):
        A = self.dummy_operation(B)
        result = A + C
        return result

So here, Example takes the place of CLASS for legibility.

One way to do this looks like the use of an if '__main__' statement (see - Python main call within class).

However, as FUNC takes arguments B and C, this will return an error:

if __name__ == '__main__':
    Example().target_function()

Out:

TypeError: target_function() missing 2 required positional arguments: 'B' and 'C'

Is there a way to pass Example(B,C), where in fact it is calling Example().FUNC(B,C) but one can still call Example().dummy_operation(A) if required?

Many thanks in advance!

user8188120
  • 883
  • 1
  • 15
  • 30
  • I don't see the point in confusing the class with one of its methods. What is the point of creating an instance of `Example`, rather than just making `target_function` a regular function? – chepner Oct 15 '19 at 15:16
  • 3
    Maybe you want [`__call__`](https://docs.python.org/3/reference/datamodel.html#emulating-callable-objects) – snakecharmerb Oct 15 '19 at 15:16
  • 2
    Do instances of your class actually store any information? If not, you can probably just put it in a separate module, import that module, then call the functions like `my_module.FUNC(A, B)` – Patrick Haugh Oct 15 '19 at 15:17
  • @chepner The point is that some users will want to use the class function FUNC as a default but will only care about the class name, whereas some who wish to dive into using more of the functionalities of the class will be able to call CLASS().FUNC2(...), but only if they actually want to use some of the subroutines. It's purely for aesthetics for those unfamiliar with the finer details of this class. The real class I'm using is much larger than this example with much more complex functionality. – user8188120 Oct 15 '19 at 15:25
  • @snakecharmerb Thanks, I'm having a read of those docs now! – user8188120 Oct 15 '19 at 15:25
  • I see no reason for there to be a class here in the first place, so your hypothetical "user preferences" don't apply. – chepner Oct 15 '19 at 15:26
  • @chepner My class has many subroutines that can be called which perform different operations...that's the point of a class. Here, one function can be used as a default operation (calling several other internal functions) and for simplicity I've made it call only one other function in the example above. I could post my real class but a 700 line long class is not helpful here so my example is just to show you the idea of what I'm trying to achieve. – user8188120 Oct 15 '19 at 15:29
  • @PatrickHaugh That's a pretty nice idea acually. It tidies it up so that we don't need the brackets anymore..almost what I'm after and a great alternative if __call__ doesn't completely solve the problem as suggested above – user8188120 Oct 15 '19 at 15:35
  • @snakecharmerb That worked perfectly thank you very much!! – user8188120 Oct 15 '19 at 15:44
  • @snakecharmerb ..the only drawback here being that now the function is called `__call__` it can no longer be called individually by it's desirable name `FUNC` – user8188120 Oct 15 '19 at 16:03
  • 1
    You could alias it by adding the line `FUNC = __call__` after the body of `__call__` (indented at the same level as the `def` statements) I think. – snakecharmerb Oct 15 '19 at 16:06
  • @snakecharmerb That worked too, thanks so much :) – user8188120 Oct 15 '19 at 16:12

1 Answers1

1

This problem was solved by @snakecharmerb in the comments.

class Example:

    def dummy_operation(self,A):
        return A*2.

    def __call__(self,B,C):
        A = self.dummy_operation(B)
        result = A + C
        return result

Example = Example()
print(Example(1,1))
print(Example.dummy_operation(1))

Out:

3.0
2.0
user8188120
  • 883
  • 1
  • 15
  • 30