2

Lets say I have a function myFunc defined as

def myFunc(value):
    return value if isinstance(value, int) else None

Now wherever in my project I use myFunc the enclosing funciton should return automatically if the value returned from myFunc is None and should continue if some integer value is returned

For example:

def dumbFunc():

    # some code
    # goes here..

    result = myFunc('foo')

    # some code
    # goes here..

This funciton should automatically behave like..

def dumbFunc():

    # some code
    # goes here..

    result = myFunc('foo')
    if not result:
        return

    # some code
    # goes here..

PS - I don't know whether this thing even possible or not.

esquarer
  • 303
  • 3
  • 12
  • So what's the problem? – kasravnd Aug 10 '17 at 10:50
  • and...........? – gsamaras Aug 10 '17 at 10:50
  • I just want to do `result = myFunc('foo')` inside `dumbFunc`. Without stating the if condition the funciton should return. – esquarer Aug 10 '17 at 10:53
  • .. you want to do an if statement without using an if statement? – Stael Aug 10 '17 at 10:54
  • 1
    But why?! That’s not how things are supposed to work. A function call having the *possible* side effect of ending the current function would be terrible. – poke Aug 10 '17 at 10:54
  • there are other ways to do this.. you could use `try: something; except: return` but that is pretty much equivalent to the `if`. What do you not like about your example? – Stael Aug 10 '17 at 10:56
  • I want an alternative to raising an exception which would just return from the current function (and not completely terminate the program). If `myFunc` is used at 100 places in my project, everywhere I need to put an if condition after it. I want to know whether it can be handled at a single place – esquarer Aug 10 '17 at 10:56

3 Answers3

3

This is simply not possible.

Apart from exceptions, you cannot give a called function the ability to impact the control flow of the calling scope. So a function call foo() can never interrupt the control flow without throwing an exception. As a consumer of the function, you (the calling function) always have the responsibility yourself to handle such cases and decide about your own control flow.

And it is a very good idea to do it like that. Just the possibility that a function call might interrupt my control flow without having a possibility to react on it first sounds like a pure nightmare. Just alone for the ability to release and cleanup resources, it is very important that the control flow is not taken from me.

Exceptions are the notable exception from this, but of course this is a deeply rooted language feature which also still gives me the ability to act upon it (by catching exceptions, and even by having finally blocks to perform clean up tasks). Exceptions are deliberately not silent but very loud, so that interruptions from the deterministic control flow are clearly visible and have a minimum impact when properly handled.

But having a silent feature that does neither give any control nor feedback would be just a terrible idea.


If myFunc is used at 100 places in my project, everywhere I need to put an if condition after it.

If your code is like that that you could just return nothing from any function that calls myFunc without having to do anything, then either you are building an unrealistic fantasy project, or you simply are not aware of the implications this can have to the calling code of the functions that would be returned that way.

poke
  • 307,619
  • 61
  • 472
  • 533
1

ok, I'll bite.

on the one hand, this isn't really possible. if you want to check something you have to have a line in your code that checks it.

there are a few ways you could achieve something like this, but i think you may have already found the best one.

you already have this function:

def myFunc(value):
    return value if isinstance(value, int) else None

I would probably have done:

def myFunc(value):
    return isinstance(value, int)

but either way you could use it:

def dumb_func():
    value = do_something()
    if myFunc(value):
        return
    do_more()
    return value

alternately you could use try and except

I would raise a TypeError, seeing as that seems to be what you are checking:

def myFunc(value):
    if not isinstance(value, int):
        raise TypeError('myFunc found that {} is not an int'.format(value))

then you can use this as such

def dumb_func():
    value = do_something()
    try:
        myFunc(value):
    Except TypeError as e:
        print e # some feedback that this has happened, but no error raised
        return
    do_more()
    return value

for bonus points you could define a custom exception (which is safer because then when you catch that specific error you know it wasn't raised by anything else in your code, also if you did that you could be lazier eg:)

Class CustomTypeError(TypeError):
    pass

def dumb_func():
    try:
        value = do_something()
        myFunc(value):
        do_more()
        return value
    Except CustomTypeError as e:
        print e # some feedback that this has happened, but no error raised
        return

but none of this gets around the fact that if you want to act based on the result of a test, you have to check that result.

Stael
  • 2,299
  • 9
  • 18
0

Python has a ternary conditional operator, and the syntax you used is right, so this will work:

def myFunc(value):
    return value if isinstance(value, int) else None

def dumbFunc():
  print("Works?")
  result = myFunc(5)
  print(result)

dumbFunc()

Result:

Works?
5

I want the function to return automatically in that case

This is not possible. To do that, you have to check the return value of myFunc() and act upon it.

PS: You could do that with a goto statement, but Python, fortunately, doesn't support this functionality.

gsamaras
  • 66,800
  • 33
  • 152
  • 256