Python syntax and semantics
The syntax of the Python programming language is the set of rules that defines how a Python program will be written and interpreted. The Python language has many similarities to Perl, C, and Java. However, there are some definite differences between the languages. It supports multiple programming paradigms, including structured, object-oriented programming, and functional programming, and boasts a dynamic type system and automatic memory management.
Python's syntax is simple and consistent, adhering to the principle that "There should be one—and preferably only one—obvious way to do it." The language incorporates built-in data types and structures, control flow mechanisms, first-class functions, and modules for better code reusability and organization. Python also uses English keywords where other languages use punctuation, contributing to its uncluttered visual layout.
The language provides robust error handling through exceptions, and includes a debugger in the standard library for efficient problem-solving. Python's syntax, designed for readability and ease of use, makes it a popular choice among beginners and professionals alike.
Design philosophy
Python was designed to be a highly readable language. It has a relatively uncluttered visual layout and uses English keywords frequently where other languages use punctuation. Python aims to be simple and consistent in the design of its syntax, encapsulated in the mantra, from the Zen of Python.This mantra is deliberately opposed to the Perl and Ruby mantra, "there's more than one way to do it".
Keywords
Python 3 has 35 keywords or reserved words; they cannot be used as identifiers.andasassertasyncawaitbreakclasscontinuedefdelelifelseexceptFalsefinallyforfromglobalifimportinislambdaNonenonlocalnotorpassraisereturnTruetrywhilewithyield
type added in Python 3.12. Unlike regular hard keywords, soft keywords are reserved words only in the limited contexts where interpreting them as keywords would make syntactic sense. These words can be used as identifiers elsewhere, in other words, match and case are valid names for functions and variables._casematchtypeFunction annotations
def haul -> Distance:
# implementation here
While annotations are optional in Python, the rest of this article will use annotations to provide clarity.
Modules and import statements
In Python, code is organized into files called modules, and namespaces are defined by the individual modules. Since modules can be contained in hierarchical packages, then namespaces are hierarchical too.In general when a module is imported then the names defined in the module are defined via that module's namespace, and are accessed in from the calling modules by using the fully qualified name.
- assume ModuleA defines two functions : func1 and func2 and one class : Class1
ModuleA.func1
ModuleA.func2
a: ModuleA.Class1 = Modulea.Class1
The
from... import... statement can be used to insert the relevant names directly into the calling module's namespace, and those names can be accessed from the calling module without the qualified name:- assume ModuleA defines two functions : func1 and func2 and one class : Class1
func1
func2 # this will fail as an undefined name, as will the full name ModuleA.func2
a: Class1 = Class1 # this will fail as an undefined name, as will the full name ModuleA.Class1
Since this directly imports names it can overwrite existing names with no warnings.
A special form of the statement is
from... import * which imports all names defined in the named package directly in the calling module's namespace. Use of this form of import, although supported within the language, is generally discouraged as it pollutes the namespace of the calling module and will cause already defined names to be overwritten in the case of name clashes. However, this page will present code as if the line "from typing import *" were included, for referring to collection types.The different import statements are demonstrated here:
- imports the argument parsing module
- imports the Pattern class from the regular expressions module
- imports all symbols inside the typing module
Using
from import statements in Python can simplify verbose namespaces, such as nested namespaces.from selenium.webdriver import Firefox
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.remote.webelement import WebElement
if __name__ "__main__":
driver: Firefox = Firefox
element: WebElement = driver.find_element
element.send_keys
action: ActionChains = ActionChains
action.key_down.send_keys.key_up.perform
Python also supports
import x as y as a way of providing an alias or alternative name for use by the calling module:import numpy as np
from numpy.typing import NDArray, float32
a: NDArray = np.arange
When a module is imported, the Python interpreter first checks if it exists in the
sys.modules cache, and reuses it if it had been imported previously, otherwise it loads it. When loading, it searches it in sys.path, and compiles it to bytecode or interprets its contents. All code in the global scope of the module is executed. However, this can be mitigated using an explicit main function, which behaves similarly to an entry point in most compiled languages, using the entry point idiom described as follows.Entry point
A pseudo-entry point can be created by the following idiom, which relies on the internal variable__name__ being set to __main__ when a program is executed, but not when it is imported as a module ; there are many variants of this structure:import sys
def main -> int:
argc: int = len # get length of argv
n: int = int
return 0
if __name__ "__main__":
sys.exit
In this idiom, the call to the named entry point
main is explicit, and the interaction with the operating system are done explicitly by library calls, which are ultimately handled by the Python runtime. This contrasts with C, where these are done implicitly by the runtime, based on convention.Indentation
Python uses whitespace to delimit control flow blocks. Python borrows this feature from its predecessor ABC: instead of punctuation or keywords, it uses indentation to indicate the run of a block.In so-called "free-format" languages – that use the block structure derived from ALGOL – blocks of code are set off with braces or keywords. In most coding conventions for these languages, programmers conventionally indent the code within a block, to visually set it apart from the surrounding code.
A recursive function named
foo, which is passed a single parameter, x, and if the parameter is 0 will call a different function named bar and otherwise will call baz, passing x, and also call itself recursively, passing x-1 as the parameter, could be implemented like this in Python:def foo -> None:
if x 0:
bar
else:
baz
foo
and could be written like this in C:
void foo
Incorrectly indented code could be misread by a human reader differently than it would be interpreted by a compiler or interpreter. For example, if the function call
foo on the last line in the example above was erroneously indented to be outside the if/else block:def foo -> None:
if x 0:
bar
else:
baz
foo
it would cause the last line to always be executed, even when
x is 0, resulting in an endless recursion.While both space and tab characters are accepted as forms of indentation and any multiple of spaces can be used, spaces are recommended and four spaces are recommended and are by far the most commonly used. Mixing spaces and tabs on consecutive lines is not allowed starting with Python 3 because that can create bugs which are difficult to see, since many text editors do not visually distinguish spaces and tabs.