I have a function:
def delete(title=None, pageid=None): # Deletes the page given, either by its title or ID ... pass
However, my intention is for the function to take only one argument (either title
OR pageid
). For example, delete(title="MyPage")
or delete(pageid=53342)
are valid, while delete(title="MyPage", pageid=53342)
, is not. Zero arguments can not be passed. How would I go about doing this?
Advertisement
Answer
There is no Python syntax that’ll let you define exclusive-or arguments, no. You’d have to explicitly raise an exception is both or none are specified:
if (title and pageid) or not (title or pageid): raise ValueError('Can only delete by title OR pageid')
The full expression can become a little tedious, especially if title
or pageid
could be set to 0
or another falsey value that is valid, so you could capture the above in a utility function:
from typing import Any def exclusive_or(left: Any, right: Any) -> bool: """Test if either left or right is true, but not both""" return (left or right) and not (left and right)
Note that this is the inverse test of what you needed for the if
test, so don’t forget to add not
:
if not exclusive_or(title, pageid): # ...
which is a lot easier to use when having to test for not None
:
if not exclusive_or(title is not None, pageid is not None): # ...
Note that I used type hints to add information to the function for type checkers and IDEs to see what kind of arguments the function takes or what the return value type is.
With type hints, you can also mark up your original function and tell those tools that your function only takes one or the other argument, by using @overload
:
@overload def delete(title: str) -> None: ... @overload def delete(pageid: int) -> None: ... def delete(title: Optional[str] = None, pageid: Optional[int] = None) -> None: """Deletes the page given, either by its title or ID""" ... pass
In an IDE like PyCharm or Visual Studio Code (with the Pylance extension installed) would show you real-time information about the function as you type:
This kind of tool integration would make it easier to use your function without triggering an exception.