Python Keywords for Functions, Modules, Classes, Variables, Coroutines and More

By:   |   Updated: 2022-11-02   |   Comments   |   Related: More > Python


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)
using return in a function

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:

creating and calling a generator function

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:

custom class with initialization and one custom method

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:

deleting a class

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))
checking if a variable is another variable/type

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:

local, global and nonlocal variables

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:

concurrent code execution with async

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:

sequential code execution

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:

assertion error

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))
data type None

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:

function with "pass" returns "None"

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


sql server categories

sql server webinars

subscribe to mssqltips

sql server tutorials

sql server white papers

next tip



About the author
MSSQLTips author Hristo Hristov Hristo Hristov is a Data Scientist and Power Platform engineer with more than 12 years of experience. Between 2009 and 2016 he was a web engineering consultant working on projects for local and international clients. Since 2017, he has been working for Atlas Copco Airpower in Flanders, Belgium where he has tackled successfully multiple end-to-end digital transformation challenges. His focus is delivering advanced solutions in the analytics domain with predominantly Azure cloud technologies and Python. Hristoís real passion is predictive analytics and statistical analysis. He holds a masterís degree in Data Science and multiple Microsoft certifications covering SQL Server, Power BI, Azure Data Factory and related technologies.

View all my tips


Article Last Updated: 2022-11-02

Comments For This Article