Use option 1 for simplicity & adherence to spec.
def foo() -> None
Option 1 & 2 are the 'same' as per PEP 484 -- Type Hints, ...
When used in a type hint, the expression
Noneis considered equivalent totype(None).
but the type-hinting specification does not use type(...).
This is why most of the examples use None as return type.
Is there a way to define a void function in python? (with no parameters). If yes, any idea how?
Thank you in advance
Python void return type annotation - Stack Overflow
why none happens on this "In Python, a void function is a function that does not return any value. When you assign the result of a void function to a variable, you get the special value None. This happens because in Python, when a function does not explicitly return a value, it implicitly returns None.
For example, consider the following void function:
def greet():
print("Hello!")
If you assign the result of this function to a variable:
result = greet()
The value of result will be None.
So, the correct answer to the question is:
d. the special value None
python - Is it always a best practice to write a function for anything that needs to repeat twice? - Software Engineering Stack Exchange
Python Void Function
Videos
Use option 1 for simplicity & adherence to spec.
def foo() -> None
Option 1 & 2 are the 'same' as per PEP 484 -- Type Hints, ...
When used in a type hint, the expression
Noneis considered equivalent totype(None).
but the type-hinting specification does not use type(...).
This is why most of the examples use None as return type.
TLDR: The idiomatic equivalent of a void return type annotation is -> None.
def foo() -> None:
...
This matches that a function without return or just a bare return evaluates to None.
def void_func(): # unannotated void function
pass
print(void_func()) # None
Omitting the return type does not mean that there is no return value. As per PEP 484:
For a checked function, the default annotation for arguments and for the return type is
Any.
This means the value is considered dynamically typed and statically supports any operation. That is practically the opposite meaning of void.
Type-hinting in Python does not strictly require actual types. For example, annotations may use strings of type names: Union[str, int], Union[str, 'int'], 'Union[str, int]' and various variants are equivalent.
Similarly, the type annotation None is considered to mean "is of NoneType". This can be used in other situations as well as return types, though you will see it most often as a return-type annotation:
bar : None
def foo(baz: None) -> None:
return None
This also applies to generic types. For example, you can use None in Generator[int, None, None] to indicate a generator does not take or return values.
Even though PEP 484 suggests that None means type(None), you should not use the latter form explicitly. The type-hinting specification does not include any form of type(...). This is technically a runtime expression, and its support is entirely up to the type checker. The mypy project is considering whether to remove support for type(None) and remove it from 484 as well.
Or maybe we should update PEP 484 to not suggest that
type(None)is valid as a type, andNoneis the only correct spelling? There should one -- and preferably only one -- obvious way to do it etc.--- JukkaL, 18 May 2018
Although it's one factor in deciding to split off a function, the number of times something is repeated shouldn't be the only factor. It often makes sense to create a function for something that's only executed once. Generally, you want to split a function when:
- It simplifies each individual abstraction layer.
- You have good, meaningful names for the split-off functions, so you don't usually need to jump around between abstraction layers to understand what's going on.
Your examples don't meet that criteria. You're going from a one-liner to a one-liner, and the names don't really buy you anything in terms of clarity. That being said, functions that simple are rare outside of tutorials and school assignments. Most programmers tend to err too far the other way.
Only if the duplication is intentional rather than accidental.
Or, put another way:
Only if you would expect them to co-evolve in the future.
Here's why:
Sometimes, two pieces of code just happen to become the same even though they have nothing to do with each other. In that case you must resist the urge to combine them, because the next time someone performs maintenance on one of them, that person will not expect the changes to propagate to a previously-nonexistent caller, and that function may break as a result. Hence you have to only factor out code when it makes sense, not whenever it seems to reduce code size.
Rule of thumb:
If the code only returns new data and doesn't modify existing data or have other side effects, then it's very likely to be safe to factor out as a separate function. (I can't imagine any scenario in which that would cause a breakage without entirely changing the intended semantics of the function, at which point the function name or signature should change too, and you'd need to be careful in that case anyway.)