Python has no void keyword for function declarations. To create a void-style function, define it with def, indent its body, and do not return a value. When execution reaches the end, Python returns None. A bare return also returns None, but stops the function immediately at that point.
For example:
def greet(name):
"""Print a greeting without returning a useful value."""
print(f"Hello, {name}!")
greet("Ada")
The call prints Hello, Ada!. Its result is still None; printing text is a side effect, not a returned value. This guide shows the syntax, explains the difference between omitting return and using a bare return, and helps you decide when a function should return data instead.
As an Amazon Associate I earn from qualifying purchases.
What “void function” means in Python
In languages that have a void return type, a function can be declared explicitly as producing no value for its caller. Python uses a different model. Every function call has a result, and a function that does not return another value produces the singleton object None.
“Void function” is therefore a useful informal description, not Python syntax. You write an ordinary function with def; there is no special declaration such as void greet(). The function may perform an action—printing, recording a message, changing program state, or coordinating another operation—without giving its caller a useful result to process.
#1 Best Overall
The official Python control-flow tutorial states that a return without an expression returns None, and that falling off the end of a function also returns None. The practical consequence is simple: omit a value-returning return when the caller should use the function for its action rather than for a computed result.
Thinking in terms of a caller contract is useful. A function such as display_report() promises an operation: call it to display the report. It does not promise a report object to store or transform. The call still evaluates to None, but that result is normally not the reason to call the function.
The basic syntax
A function definition has four essential parts:
defintroduces the definition.- A name identifies the function, such as
greet. - Parentheses hold parameters. They can be empty or contain names the caller supplies.
- A colon and indented body contain the statements that run when the function is called.
Here is the smallest useful void-style function:
def announce(message):
print(message)
The definition alone does not execute the body. Call it with an argument:
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →announce("Deployment complete")
Python then evaluates print(message). Because the body has no value-returning return, the call finishes with None.
A function can also take no parameters:
def show_ready():
print("Ready")
show_ready()
Empty parentheses in the definition and call mean that this operation does not require input. Parameters do not determine whether a function is void-style; the return behavior does.
Adding a docstring
An optional first string expression in the body is the function’s docstring. It documents the function’s purpose for readers and tools:
def announce(message):
"""Display a status message without returning it."""
print(message)
The docstring does not change the return behavior. It remains a void-style function because execution reaches the end without returning a value. A useful docstring can state both the action and the caller contract, for example, “Print a formatted total; the call returns None.”
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Step-by-step: create and call one
- Choose an action. Decide what the function should do, such as display a greeting.
- Write the header. Start with
def, a descriptive name, parentheses, and a colon. - Indent the body. Put the statements that perform the action on indented lines below the header.
- Leave out
returnunless you need an early exit. Reaching the end automatically producesNone. - Call the function. Supply arguments in parentheses when the definition has parameters.
def greet(name):
"""Print a greeting without returning a useful value."""
print(f"Hello, {name}!")
greet("Ada")
The visible output is:
Hello, Ada!
The output comes from print. It is not the value of the call. To inspect the call’s result, assign it or pass the call to print:
result = greet("Ada")
print(result)
This produces the greeting first and then None on the next line.
You can write the call directly inside another print while learning:
print(greet("Ada"))
First, greet prints Hello, Ada!. Then the outer print prints the call’s result, None. The two lines are produced by two different print operations.
What a function returns when you omit return
Python inserts the equivalent of a None result when control reaches the end of a function. You do not need to write return None for ordinary fall-through behavior.
def announce(message):
print(message)
result = announce("Done")
print(result) # None
The name result receives None, even though the function printed Done. A caller can test this explicitly with is None:
Rank #2
if announce("Saved") is None:
print("The function did not return a value")
Use is None when checking for this specific object. Do not mistake a printed message for a returned string; the two outputs travel through different channels.
“No return value” is therefore shorthand for “the function returns None, and callers are not expected to use that result.” This distinction matters when reading code, assigning a call to a variable, or passing a call as an argument. The assignment is valid, but the assigned value is None.
Free tools Windows power users keep installed
One-click scans. No signup required.
Omitted return versus bare return
There are two ways to finish without a useful value. They have the same result but different control flow:
| Form | What happens | Result of the call | When to use it |
|---|---|---|---|
No return |
Statements continue until the indented body ends. | None |
Use when the function should run all the way through its body. |
Bare return |
Execution exits immediately at that statement. | None |
Use when a condition requires an early stop. |
return with an expression |
Execution exits and supplies the expression’s value. | The evaluated expression | Use only when the caller is meant to receive a value. |
A bare return has no expression after the keyword:
def announce_if_present(message):
if message == "":
return
print(message)
An empty message causes an immediate exit and the call returns None. A non-empty message is printed, and the function still reaches its end and returns None. In both branches the caller receives no useful value; the difference is whether the later statements run.
Consider the position of the bare return carefully. In this example it prevents the print statement from running. Moving it after the print would not prevent that output; it would simply stop any statements that followed it. The keyword is a control-flow tool, not a marker that makes a function void.
Printing is not returning
This distinction causes most confusion with void-style functions. print sends text to the program’s output stream. return hands a value back to the code that called the function. A function can print something and still return None.
def show_status():
print("Ready")
value = show_status()
print(f"Returned value: {value!r}")
The output is:
Ready
Returned value: None
If the caller needs the text for another operation, return it instead:
def status_text():
return "Ready"
value = status_text()
print(value)
That second function is not void-style: its call returns the string "Ready". You can still print the returned string, but the design is different because callers are expected to use the value.
The same separation applies to a function that displays a sequence. A function can print each item as it works and return None; another function can build and return a list for the caller. Choose based on what the next piece of code needs. If a caller must sort, format, store, or test the data, return the data. If the function’s purpose is only an action and no result is needed, a void-style design is appropriate.
Printing inside a function does not make its output available to the surrounding expression. For example, assigning value = show_status() stores the return result, not the characters that appeared on screen. To make those characters available as data, the function must use a value-returning return.
Recommended Free Tools
Designing a useful void-style function
Give the action a clear name
Names such as greet, announce, display_report, and write_log describe an operation. A name that sounds like a value, such as get_message, can mislead callers into expecting a return value.
Verb-oriented names make the intent visible at the call site. display_total(19.5) reads like an instruction, while a name such as total(19.5) could suggest that the caller receives a number. Naming cannot change Python’s behavior, but it can make the intended contract clear.
Keep the caller contract obvious
Document the side effect in a docstring and make the absence of a useful return value intentional:
def display_total(amount):
"""Print a formatted total; the call returns None."""
print(f"Total: ${amount:.2f}")
The caller knows to invoke display_total(19.5) for its output, not to assign the result and expect a number.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallIf the function has more than one visible action, describe that in the docstring as well. A function that prints and also returns a value has two observable behaviors. A caller should not have to guess whether the printed text, the returned value, or both are part of the intended interface.
Use an early exit only for control flow
If an invalid or empty input means there is nothing to do, a bare return communicates that decision:
def display_name(name):
"""Print a name when one was supplied."""
if not name:
return
print(name)
Both the early branch and the normal branch return None. The bare return is valuable because it prevents the print statement from running; it is not needed merely to make the function “void.”
Separate action from data production
A practical design question is: what should the caller do next? If the next operation needs a value, have the function return that value. If the next operation is simply complete after the side effect, omit a value-returning return. Keeping those roles separate avoids a caller that must depend on screen output when it really needs data.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteCommon mistakes and how to fix them
Writing a nonexistent void declaration
This is invalid Python:
void greet(name):
print(name)
Start with def instead:
def greet(name):
print(name)
Python’s return behavior supplies None automatically.
Assuming printed text becomes the result
This code does not return "Done":
def finish():
print("Done")
message = finish()
print(message) # None
Replace print with return only if callers need the string:
def finish():
return "Done"
Forgetting indentation
The body must be indented below the header. Keep the indentation consistent so Python can identify the function’s block:
def greet(name):
print(f"Hello, {name}!")
A statement aligned with def is outside the function. An incorrectly indented statement can raise an indentation error or change which block it belongs to.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Returning accidentally from one branch
If one branch returns a value and another falls through, callers receive different types:
def label(enabled):
if enabled:
return "Enabled"
print("Disabled")
Here the true branch returns a string while the false branch returns None. That may be deliberate, but it is not a consistently void-style function. If no branch should return a value, use a bare return for early exits and avoid value expressions:
def report(enabled):
if not enabled:
return
print("Enabled")
Adding return None everywhere
return None is valid, but it is usually unnecessary when the function simply runs to completion. Omitting the statement makes the intent clear: perform the action, then finish. Use an explicit bare return when the important fact is that execution stops at that point.
Writing return None can still be useful when you want to make the result explicit at a particular branch. The key difference is not the resulting value—both forms produce None—but whether the statement documents an intentional exit or merely repeats normal fall-through behavior.
How to check the behavior
You can verify a function’s result without changing the function itself:
- Call the function and assign the result to a variable.
- Observe any output produced by the function.
- Inspect the variable with
printor compare it withis None.
def announce(message):
print(message)
result = announce("Ready")
assert result is None
The assertion passes after Ready is printed. This checks the return contract separately from the visible side effect. If you instead write assert result == "Ready", the assertion fails because the text was printed, not returned.
For a function with an early exit, check both paths:
def announce_if_present(message):
if message == "":
return
print(message)
assert announce_if_present("") is None
assert announce_if_present("Ready") is None
The first call produces no message and exits at the bare return. The second prints Ready and then falls off the end. Both assertions test the same return contract while the visible side effects differ.
When to return a value instead
Use a value-returning function when another part of the program must consume the result. Returning a value lets the caller assign it, combine it with other expressions, test it, or pass it to another function:
def make_greeting(name):
return f"Hello, {name}!"
greeting = make_greeting("Ada")
print(greeting)
Use a void-style function when the operation itself is the goal and no useful result needs to flow back:
def print_greeting(name):
print(f"Hello, {name}!")
Neither style is automatically better. The correct choice depends on the caller’s needs. A function that both prints and returns a value can be valid, but it creates two observable behaviors; document that deliberately so callers know whether to rely on the output, the return value, or both.
A useful comparison is the tutorial’s print-versus-return pattern: one function prints a Fibonacci series as an action, while a separate function returns a list so the caller can work with the data. The same design choice applies to greetings, status messages, reports, and other operations. Ask whether the next statement needs data or merely needs the action to happen.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Frequently asked questions
Does Python have a void keyword?
No. Python uses the normal def syntax for every function. “Void function” describes a function whose caller is not meant to use a returned value; Python represents that result as None.
What does a function return if it has no return statement?
When execution reaches the end of the function, the call returns None. You can store the call in a variable and verify it with result is None.
What does a bare return do?
A bare return exits the function immediately and returns None. Use it when a condition means that later statements should not run.
Is print() the same as return?
No. print() sends text to output. return supplies a value to the calling code. A function may print a message and still return None.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Should I write return None?
Not for ordinary completion. Omitting return already produces None. Use a bare return when you need an early exit; an explicit return None is valid when you want to state the result directly.
Can a void-style function accept parameters?
Yes. Parameters control the input supplied to the action, not whether the function returns a value. def announce(message): accepts a message and still returns None when it finishes.
How can I tell whether a function printed something or returned it?
Assign the call to a variable and inspect that variable. The printed text appears separately, while the variable contains the return result. For a void-style function, print(result) displays None.
What if one branch returns a string and another branch has no return?
The first branch returns the string and the other branch returns None. That is a mixed return contract, not a consistently void-style function. Use only bare returns or fall-through behavior if every path should return None.
Does a docstring make a function return a value?
No. A docstring is an optional first string expression that documents the function. It does not change the implicit None result.
Reference behavior in the official documentation
The Python tutorial’s control-flow chapter covers function definitions, docstrings, bare returns, implicit None, and the difference between printing and returning. Its concise rule is that return without an expression returns None, and falling off the end of a function also returns None. The corresponding CPython tutorial source contains the same explanation.
The documentation landing page is currently labeled Python 3.15.0; labels can change as new releases are published. The function behavior described here is the documented Python behavior rather than a special feature of a paid tool or a particular editor.
Quick checklist
- Start the definition with
def name(parameters):. - Indent every statement in the body.
- Use an optional first string expression as a docstring.
- Omit
returnwhen the function should run to its end and produce no useful value. - Use a bare
returnwhen a branch must stop early without returning data. - Remember that both forms produce
None. - Do not confuse text printed by
printwith the value returned to the caller. - Use
return expressionwhen callers genuinely need a result. - Choose action-oriented names such as
announceordisplay_report. - Document important side effects and any deliberate combination of printing and returning.
- Check the result with
is Nonewhen you need to verify the return contract.
Frequently Asked Questions
How do I create a void function in Python?
Use the ordinary def name(parameters): syntax, indent the body, and omit a value-returning return. When the body ends, Python returns None.
Recommended Free Tools
What is the difference between omitting return and using bare return?
Both produce None. Omitting return lets all remaining statements run to the end; a bare return exits immediately.
Why does my function print text but assign None?
print() sends text to output, while return supplies a value to the caller. Printing a message does not return that message.
Should I use return None in every void-style function?
No. Normal fall-through already returns None. Use a bare return for an early stop, or write return None only when making the result explicit is useful.
How can I verify that a function returns None?
Assign the call to a variable and test it with result is None. This lets you check the return value separately from any output the function displays.
Can a function with parameters still be void-style?
Yes. Parameters provide input for the action; they do not determine the return behavior. A function can accept several parameters and still finish with None.
What happens if only one branch returns a value?
That branch returns its value, while a branch that falls through returns None. The function then has different return behavior on different paths.
The Bottom Line
Python does not declare void functions with a special keyword. Define an ordinary function with def, indent its action, and omit a value-returning return; reaching the end returns None. Use a bare return only when a branch must stop early. Remember that printed output is not a returned value, and return an expression whenever the caller needs data to store, test, or transform.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

