Problem
The Python programming language has important “reserved” commands called keywords. Each keyword provides a special instruction to the interpreter. Every data professional should be familiar with all Python keywords to use them at the right time efficiently.
Solution
This Python tutorial presents the second batch of keywords grouped by function.
In the previous Python tutorial, we examined the following categories and keywords:
- Boolean Value (
True
,False
), - Conditionals (
if
,elif
,else
), - Logical operators (
and
,or
,not
), - Membership check (
in
), - Exception Handling (
try block
,except
,finally
,raise
) - and Loops (
for
,while loop
,break
,continue
).
In this Python tutorial, we will continue with the final set of categories and related keywords:
- Function related (
def
,lambda
,return
,yield
), - Module related (
from
,import
,as
), - Class related (
class
,del
,is
), - Variable related (
global variable
,nonlocal
), - Coroutines (
async
,await
) - and Others (
assert
,None
,pass
).
Function Related
def lambda return yield
Starting with def keyword
, it is used to create a function:
def say_hello(): print('Hello World')
def
is short for definition. It is good practice to name your functions with verbs and ensure that one function does one thing. Functions that do many operations can be difficult to read and support.
On the other hand, the lambda
keyword allows the creation of anonymous functions inline. These constructs do not need a name. Therefore, they cannot be invoked later like a normal function. All lambda
expressions return the function itself.
Next, the return
keyword is an important command that allows a function to return a certain result. In the example above, our say_hello()
function does not return anything. Instead, it prints out a message. We can, however, make it return a string that can be later assigned to a variable that can then be printed:
def say_hello(): return 'Hello World' result = say_hello() print(result)

For more explanations on functions, check out my tip: How to Define and Call Functions in Python.
Lastly, in this section, we have the yield
keyword. A regular function can be converted to a generator function using the yield
keyword:
def say_hello(): for i in range(3): yield 'Hello World'
This example creates a function that will output “Hello World” three times, one at a time. On the fourth time, there will be an error because the generator object is now empty:

The special generator object yields one result at a time instead of the whole sequence at once. To learn more, check out this handy overview of iterables vs. iterators vs. generators: Python Iterable vs. Iterator vs. Generator with Sample Code.
Module Related
from import as
This next category of keywords in the Python import system is what takes care of working with modules. You access another module from the current one by importing it using the import
keyword. For example:
import pandas
This import statement imports the module named pandas by first searching for the named module, then binding it to the results of that search to a name in the local scope. However, it is better and stylistically more appealing to state:
import pandas as pd
Now all classes that are part of the pandas namespace are available in the current local namespace from the object pd
.
Additionally, you can import a particular class from a specific module if you expect it will be the only thing you will need in the current namespaces. Therefore, it is more optimal than importing everything from the target module:
from pandas import dataframe as df
You use as
to assign an alias like the examples so far. Also, when importing modules, it is good practice to follow this order:
- Standard modules – e.g., sys, os, re
- Third-party modules (anything installed in Python’s site-packages directory) – e.g., mx.DateTime, ZODB, PIL.Image, etc.
- Modules you have developed locally.
Class Related
class del is
There is hardly enough space in this article to go over classes in detail. As far as the keywords are concerned, the class
keyword is used to create a new type of object. Once we have this type, we can create instances of it. A class is a bundle of data and functionality, i.e., it can both store information and perform certain actions. In the broadest terms, the class keyword creates the new data type. For example:
class MyData: def __init__(self, table, top): self.table = table self.top = top def query(self): statement = f'SELECT top {self.top} FROM {self.table}' return statement new_data = MyData('Employees',10) query = new_data.query() print(query)
This example shows how we can use a class to:
- Make a custom object to store and construct dynamic SQL queries.
- Refer to queries by making a new instance of the custom data class.
- Store the result set in a class attribute.
In the example, we print the actual SQL statement to the console:

On the other hand, with del
, you can delete an object:
del my_class
For example, using the object name from the previous example:
print(new_data) del new_data print(new_data)
First, we get the name and address in memory of our object. After deleting it, we get an error. There is no object called new_data
instance of MyData
anymore:

Finally, with is
, we can check if two objects are the same object. Here, this means pointing to the same address in memory:
new_data = MyData('Employees',10) more_data = new_data print(more_data is new_data) print(isinstance(new_data,MyData))

Note how the more_data
variable points to the same object, like an optimization Python does. Therefore, when compared with is
, the two instances return True
. In contrast, the isinstance
built-in method tests if an object is an instance of a particular class.
Variable Related
The global
and nonlocal
keywords allow manipulating the scope of a variable. By default, all variables are global, i.e., accessible in the current namespace. On the other hand, all variables declared inside a function are local to the function namespace. global
and nonlocal
allow accessing a local variable in the global scope. Consider this example:
def scope_test(): def do_local(): a = 'local var' def do_nonlocal(): nonlocal a a = 'nonlocal var' def do_global(): global a a = 'global var' a = 'var' do_local() print('After local assignment:', a) do_nonlocal() print('After nonlocal assignment:', a) do_global() print('After global assignment:', a) scope_test() print("In global scope:", a)
The output is:

The variable a
is local to both scope_test()
and do_local()
functions. This behavior is by default, so the binding was not changed. do_nonlocal()
, however, binds the variable identifier to the value of the same variable in the nearest enclosing scope, which in this case is the function do_nonlocal. Finally, the global assignment do_global()
changes the value of the variable in the global scope.
An important note is that the variable changes depending on the function and when it is called. This example illustrates all practical options. In a real scenario, the value of variable a
will be defined based on which function was called last.
Coroutines
Using async
and await
and the asyncio library, we can write concurrent code that can execute faster in certain situations, e.g., working with API’s or context managers. In general, Python code executes sequentially, i.e., one task must be completed for another to start and complete. In a simple script, this can hardly be a concern. However, in more complex request-response scenarios, the program’s execution speed can be vastly improved by executing tasks concurrently and asynchronously.
Here is an example: first, we have a block of code calling the do_smth()
function asynchronously. Then, it is the same function called sequentially:
import asyncio import time async def do_smth(): print('hello') await asyncio.sleep(1) print('world') async def main(): await asyncio.gather(do_smth(), do_smth(), do_smth()) s = time.perf_counter() asyncio.run(main()) elapsed = time.perf_counter() - s print(f'executed in {elapsed:0.2f} s')
The result:

On the contrary, here is the sequential execution:
import time def do_smth(): print('hello') time.sleep(1) print('world') def main(): for _ in range(3): do_smth() s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f'executed in {elapsed:0.2f} s')
The result:

Others
Below are keywords that do not directly belong to the other categories:
assert None pass
Starting with assert
, it is used to test and debug the code. For example:
x = 1 assert x == 2, 'x must be 1'
If the condition returns False, AssertionError
is raised:

Next, in this category, we have None
. This is a special type of empty value, a sort of placeholder with its own type. None
is not 0, null, empty string, or any other empty existing datatype or value:
x = None print(type(x))

Finally, we have pass
, which applies to loops, conditional statements, methods, and classes. It is used to create a placeholder for a future block of code. For example, we can name a function in our code but leave the implementation for later:
def say_hello(): pass
In fact, a function like that will return the NoneType
:

Conclusion
In this Python keyword miniseries, we examined the remaining keywords related to modules, classes, variables, coroutines, and several other keywords. Knowing how these keywords affect your program is an important stepping stone for every Python programmer and data professional.
Next Steps