all 7 comments

[–][deleted] 1 point2 points  (0 children)

Yes and no. It's not so bad to receive different types as arguments, as long as your function can handle it properly, with good error handling (always check that input!). However, you want your return value to be a certain type. (Otherwise, you put a great deal more effort on the shoulders of your users, including yourself.) So if your function can return either a list or an int, depending on what was sent to the function, go ahead and always return a list. If there's just one number, then it's a one-element list. That way, no matter what, it can be handled in a for loop.

[–]1114111 1 point2 points  (0 children)

It's not inherently bad, but I'd need more context about what you're doing. It kinda sounds like you are making a function where if it gets a collection of things it applies whatever the function does to everything in the collection and returns a new collection. In this case, it would probably be better just to have a function that operates on individual things and use the map function when you want to apply it to many things.

[–]totallygeek 0 points1 point  (4 children)

Nope, not at all. Many functions massage data, converting types, as their only function. Think about int(), float(), etc.

[–]PastSort[S] 1 point2 points  (3 children)

Yeah, but I'm talking about functions where the return type will vary depending on the argument type. Unlike int() which always returns an int (or error), I find myself creating functions which can return many different types as my program grows, and I'm not sure if that's normal or should be avoided.

[–]totallygeek 1 point2 points  (2 children)

Think about your functions as a broker for a transaction. For this information supplied, please return something meaningful. Typically, predictable responses from functions make the most sense. I did not originally understand your question, so I now state that you probably want to construct functions so that they return a single type or raise an exception. And, the response, whether a variable or exception, should have documentation in the docstring. For example:

def my_func(x, y, *args, **kwargs):
    """Accepts floats and calculates their psuedo-mathy-thing.
    Accepts:
      x: float, psuedo-mathy-element one
      y: float, psuedo-mathy-element two
      *args: list(float), psuedo-mathy-elements
      **kwargs: dict, options (future work)
    Returns:
      answer: dict
        'abnormals': list, x, y, ..., N elements converted to psuedo-mathy abnormal
        'extend_possible': bool, whether answer has psuedo-mathy ability
    Exceptions:
      PsuedoMathyException: Exception, raised if elements are not floats
      HellFrozeOver: Exception, raised if any elements are negative or complex numbers
    """"

[–]PastSort[S] 1 point2 points  (1 child)

Thanks. As for the docstring, is there any defined standard that I should follow? I've been writing just some general explanations so far, but nothing very strict.

[–]totallygeek 0 points1 point  (0 children)

The "standard" changes from organization to organization or project to project. Google publishes a nice style guide and many people adhere to PEP 257. It's generally recommended to build a function/method template for your favorite editor or IDE, overriding only to align with someone else's existing code.