DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
FREEDOM251

Freedom251 › Blog › none

Create Python Functions That Return None (Void-Style Functions Explained)

By Freedom251 Team · · 14 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“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.

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:

  1. def introduces the definition.
  2. A name identifies the function, such as greet.
  3. Parentheses hold parameters. They can be empty or contain names the caller supplies.
  4. 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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Step-by-step: create and call one

  1. Choose an action. Decide what the function should do, such as display a greeting.
  2. Write the header. Start with def, a descriptive name, parentheses, and a colon.
  3. Indent the body. Put the statements that perform the action on indented lines below the header.
  4. Leave out return unless you need an early exit. Reaching the end automatically produces None.
  5. 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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:

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to check the behavior

You can verify a function’s result without changing the function itself:

  1. Call the function and assign the result to a variable.
  2. Observe any output produced by the function.
  3. Inspect the variable with print or compare it with is 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 return when the function should run to its end and produce no useful value.
  • Use a bare return when a branch must stop early without returning data.
  • Remember that both forms produce None.
  • Do not confuse text printed by print with the value returned to the caller.
  • Use return expression when callers genuinely need a result.
  • Choose action-oriented names such as announce or display_report.
  • Document important side effects and any deliberate combination of printing and returning.
  • Check the result with is None when 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

noneprogramming tutorialsPythonPython Functionsreturn statement

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.