FazBrowse Wikipedia Viewer | Main Page |
Search Wikipedia:
|
Viewing: https://en.wikipedia.org/wiki/Python_syntax_and_semantics

Python syntax and semantics

Contents
Keywords
Function annotations
Modules and import statements
    Entry point
Indentation
Data structures
        Raw strings
        Unicode
Operators
    Arithmetic
    First-class functions
    Generators
    With statement
    Properties
    Descriptors
    Class and static methods
Exceptions
Decorators

A snippet of Python code demonstrating binary search

The syntax of the Python programming language is the set of rules that defines how a Python program will be written and interpreted (by both the runtime system and by human readers). 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 programming, 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.""There should be one— and preferably only one —obvious way to do it", 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

edit

Python 3 has 35 keywords or reserved words; they cannot be used as identifiers.

and</code>\n*<code>as</code>\n*<code>assert</code>\n*<code>async</code>",{"template":{"target":{"wt":"refn","href":"./Template:Refn"},"params":{"group":{"wt":"note"},"name":{"wt":"keywordIn35"},"1":{"wt":"<code>async</code> and <code>await</code> were introduced in Python 3.5.<ref>{{cite web |url=https://docs.python.org/3/whatsnew/3.5.html#new-keywords |title=New Keywords |work=Python v3.5 documentation |publisher=Docs.python.org |access-date=2016-06-01 |archive-url=https://web.archive.org/web/20160618215313/https://docs.python.org/3//whatsnew/3.5.html#new-keywords |archive-date=2016-06-18 |url-status=live }}</ref>"}},"i":1}},"\n*<code>await</code>",{"template":{"target":{"wt":"refn","href":"./Template:Refn"},"params":{"group":{"wt":"note"},"name":{"wt":"keywordIn35"}},"i":2}},"\n*<code>break</code>\n*<code>class</code>\n*<code>continue</code>\n*<code>def</code>\n*<code>del</code>\n*<code>elif</code>\n*<code>else</code>\n*<code>except</code>\n*<code>False</code>",{"template":{"target":{"wt":"refn","href":"./Template:Refn"},"params":{"group":{"wt":"note"},"name":{"wt":"becameKeywordIn3"},"1":{"wt":"<code>True</code> and <code>False</code> became keywords in Python 3.0. Previously they were [[global variable]]s."}},"i":3}},"\n*<code>finally</code>\n*<code>for</code>\n*<code>from</code>\n*<code>global</code>\n*<code>if</code>\n*<code>import</code>\n*<code>in</code>\n*<code>is</code>\n*<code>lambda</code>\n*<code>None</code>\n*<code>nonlocal</code>",{"template":{"target":{"wt":"refn","href":"./Template:Refn"},"params":{"group":{"wt":"note"},"name":{"wt":"keywordIn3"},"1":{"wt":"<code>nonlocal</code> was introduced in Python 3.0."}},"i":4}},"\n*<code>not</code>\n*<code>or</code>\n*<code>pass</code>\n*<code>raise</code>\n*<code>return</code>\n*<code>True</code>",{"template":{"target":{"wt":"refn","href":"./Template:Refn"},"params":{"group":{"wt":"note"},"name":{"wt":"becameKeywordIn3"}},"i":5}},"\n*<code>try</code>\n*<code>while</code>\n*<code>with</code>\n*<code>yield</code>\n",{"template":{"target":{"wt":"div col end","href":"./Template:Div_col_end"},"params":{},"i":6}}]}'>
  • and
  • as
  • assert
  • async
  • await
  • break
  • class
  • continue
  • def
  • del
  • elif
  • else
  • except
  • False
  • finally
  • for
  • from
  • global
  • if
  • import
  • in
  • is
  • lambda
  • None
  • nonlocal
  • not
  • or
  • pass
  • raise
  • return
  • True
  • try
  • while
  • with
  • yield

In addition, Python 3 also has 4 soft keywords, including 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.

Function annotations

edit

Function annotations (type hints) are defined in PEP 3107. They allow attaching data to the arguments and return of a function. The act of annotations is not defined by the language, and is left to third party frameworks. For example, a library could be written to handle static typing:

Distance:\n # implementation here\n"}}'>defhaul(item: Haulable, *vargs: PackAnimal) -> Distance: # implementation here

While annotations are optional in Python, the rest of this article will use annotations to provide clarity.

Modules and import statements

edit

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.

importnumpyasnp importpyarrowaspa fromnumpy.typingimport NDArray a: NDArray[np.float32] = np.arange(1000, dtype=np.float32) t: pa.Table = pa.table({"a": a})

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

edit

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 (in which case it is instead set to the module name); there are many variants of this structure:

int:\n argc: int = len(argv) # get length of argv\n n: int = int(argv[1])\n print(n + 1)\n return 0\n\nif __name__ == \"__main__\":\n sys.exit(main(sys.argv))\n"}}'>importsys defmain(argv: list[str]) -> int: argc: int = len(argv) # get length of argv n: int = int(argv[1]) print(n + 1) return 0 if __name__ == "__main__": sys.exit(main(sys.argv))

In this idiom, the call to the named entry point main is explicit, and the interaction with the operating system (receiving the arguments, calling system exit) 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

edit

Python uses whitespace to delimit control flow blocks (following the off-side rule). 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:

None:\n if x == 0:\n bar()\n else:\n baz(x)\n foo(x - 1)\n"}}'>deffoo(x: int) -> None: if x == 0: bar() else: baz(x) foo(x - 1)

and could be written like this in C:

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.

Data structures

edit

Since Python is a dynamically-typed language, Python values, not variables, carry type information. All variables in Python hold references to objects, and these references are passed to functions. Some people (including Python creator Guido van Rossum himself) have called this parameter-passing scheme "call by object reference". An object reference means a name, and the passed reference is an "alias", i.e. a copy of the reference to the same object, just as in C/C++. The object's value may be changed in the called function with the "alias", for example:

None:\n l.append(\"x\")\n print(l)\n\nprint(my_func(my_list))\n# prints ['a', 'b', 'c', 'x']\nprint(my_list)\n# prints ['a', 'b', 'c', 'x']\n"}}'>my_list: list[str] = ["a", "b", "c"] defmy_func(l: list[str]) -> None: l.append("x") print(l) print(my_func(my_list)) # prints ['a', 'b', 'c', 'x'] print(my_list) # prints ['a', 'b', 'c', 'x']

Function my_func changes the value of my_list with the formal argument l, which is an alias of my_list. However, any attempt to operate (assign a new object reference to) on the alias itself will have no effect on the original object.print('''Dear {recipient}, I wish you to leave Sunnydale and never return. Not Quite Love, {sender} '''.format(sender="Buffy the Vampire Slayer", recipient="Spike"))

Raw strings

edit

Finally, all of the previously mentioned string types come in "raw" varieties (denoted by placing a literal r before the opening quote), which do no backslash-interpolation and hence are very useful for regular expressions; compare "@-quoting" in C#. Raw strings were originally included specifically for regular expressions. Due to limitations of the tokenizer, raw strings may not have a trailing backslash. Creating a raw string holding a Windows path ending with a backslash requires some variety of workaround (commonly, using forward slashes instead of backslashes, since Windows accepts both).

Examples include:

title: str = "One Good Turn: A Natural History of the Screwdriver and the Screw"

Unicode

edit

Since Python 3.0, the default character set is UTF-8 both for source code and the interpreter. In UTF-8, unicode strings are handled like traditional byte strings. This example will work:

my_second_list: list[int] = [] my_second_list.append(4) my_second_list.append(5)

Tuples (class tuple) are immutable sequences of items of arbitrary types. There is also a special syntax to create tuples

my_dictionary: dict[Any, Any] = {"key 1": "value 1", 2: 3, 4: []}

The dictionary syntax is similar to the set syntax; the difference is the presence of colons. The empty literal {} results in an empty dictionary rather than an empty set, which is instead created using the non-literal constructor: set().

Operators

edit

Arithmetic

edit

Python includes the +, -, *, / ("true division"), // (floor division), % (modulus), and ** (exponentiation) operators, with their usual mathematical precedence.

In Python 3, x / y performs "true division", meaning that it always returns a float, even if both x and y are integers that divide evenly.

One such construction is the list comprehension, which can be expressed with the following format:

T: TypeVar = TypeVar("T") defqsort(l: list[T]) -> list[T]: if l == []: return [] pivot: T = l[0] return (qsort([x for x in l[1:] if x < pivot]) + [pivot] + qsort([x for x in l[1:] if x >= pivot]))

Python 2.7+ also supports set comprehensions and dictionary comprehensions.

First-class functions

edit

In Python, functions are first-class objects that can be created and passed around dynamically.

Python's limited support for anonymous functions is the lambda construct. An example is the anonymous function which squares its input, called with the argument of 5:

called_yet = False defincorrect_tracker() -> None: called_yet = True # Creates a new variable instead of updating the other called_yet incorrect_tracker() print(called_yet) # False

Declaring a variable global or nonlocal will override this behavior, allowing assignment to outer variables.

None:\n global called_yet\n called_yet = True # Reassigns called_yet from the global scope\n\ntracker()\nprint(called_yet) # True\n"}}'>called_yet = False deftracker() -> None: global called_yet called_yet = True # Reassigns called_yet from the global scope tracker() print(called_yet) # True

Generators

edit

Introduced in Python 2.2 as an optional feature and finalized in version 2.3, generators are Python's mechanism for lazy evaluation of a function that would otherwise return a space-prohibitive or computationally intensive list.

This is an example to lazily generate the prime numbers:

Iterator[int]:\n primes: list[int] = []\n for n in itertools.count(start = 2):\n if stop_at is not None and n > stop_at:\n return # raises the StopIteration exception\n composite: bool = False\n for p in primes:\n if not n % p:\n composite = True\n break\n elif p ** 2 > n:\n break\n if not composite:\n primes.append(n)\n yield n\n"}}'>importitertools defgenerate_primes(stop_at: Optional[int] = None) -> Iterator[int]: primes: list[int] = [] for n in itertools.count(start = 2): if stop_at is not None and n > stop_at: return # raises the StopIteration exception composite: bool = False for p in primes: if not n % p: composite = True break elif p ** 2 > n: break if not composite: primes.append(n) yield n

When calling this function, the returned value can be iterated over much like a list:

Introduced in Python 2.4, generator expressions are the lazy evaluation equivalent of list comprehensions. Using the prime number generator provided in the above section, we might define a lazy, but not quite infinite collection.

squares = dict((n, n * n) for n in range(5)) # in Python 3.5 and later the type of squares is dict[int, int] print(squares) # prints {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Python 2.7 and 3.0 unified all collection types by introducing dictionary and set comprehensions, similar to list comprehensions:

OOP doctrines such as the use of accessor methods to read data members are not enforced in Python. Just as Python offers functional-programming constructs but does not attempt to demand referential transparency, it offers an object system but does not demand Object-oriented programming</span>"}]],"parts":[{"template":{"target":{"wt":"Abbr","href":"./Template:Abbr"},"params":{"1":{"wt":"OOP"},"2":{"wt":"Object-oriented programming"}},"i":0}}]}'>OOP behavior. Moreover, it is always possible to redefine the class using properties (see Properties) so that when a certain variable is set or retrieved in calling code, it really invokes a function call, so that spam.eggs = toast might really invoke spam.set_eggs(toast). This nullifies the practical advantage of accessor functions, and it remains Object-oriented programming</span>"}]],"parts":[{"template":{"target":{"wt":"Abbr","href":"./Template:Abbr"},"params":{"1":{"wt":"OOP"},"2":{"wt":"Object-oriented programming"}},"i":0}}]}'>OOP because the property eggs becomes a legitimate part of the object's interface: it need not reflect an implementation detail.

In version 2.2 of Python, "new-style" classes were introduced. With new-style classes, objects and types were unified, allowing the subclassing of types. Even entirely new types can be defined, complete with custom behavior for infix operators. This allows for many radical things to be done syntactically within Python. A new method resolution order for multiple inheritance was also adopted with Python 2.3. It is also possible to run custom code while accessing or setting attributes, though the details of those techniques have evolved between Python versions.

With statement

edit

The with statement handles resources, and allows users to work with the Context Manager protocol. One function (__enter__()) is called when entering scope and another (__exit__()) when leaving. This prevents forgetting to free the resource and also handles more complicated situations such as freeing the resource when an exception occurs while it is in use. Context Managers are often used with files, database connections, test cases, etc.

Properties

edit

Properties allow specially defined methods to be invoked on an object instance by using the same syntax as used for attribute access. An example of a class defining some properties is:

None:\n self._a: int = 0\n\n @property\n def a(self) -> int:\n return self._a\n\n @a.setter # makes the property writable\n def a(self, value: int) -> None:\n self._a = value\n"}}'>classMyClass: def__init__(self) -> None: self._a: int = 0 @property defa(self) -> int: return self._a @a.setter # makes the property writable defa(self, value: int) -> None: self._a = value

Descriptors

edit

A class that defines one or more of the three special methods __get__(self, instance, owner), __set__(self, instance, value), __delete__(self, instance) can be used as a descriptor. Creating an instance of a descriptor as a class member of a second class makes the instance a property of the second class.

Class and static methods

edit

Python allows the creation of class methods and static methods via the use of the @classmethod and @staticmethod decorators. The first argument to a class method is the class object instead of the self-reference to the instance. A static method has no special first argument. Neither the instance, nor the class object is passed to a static method.

Exceptions

edit

Python supports (and extensively uses) exception handling as a means of testing for error conditions and other "exceptional" events in a program.

Python style calls for the use of exceptions whenever an error condition might arise. Rather than testing for access to a file or resource before actually using it, it is conventional in Python to just go ahead and try to use it, catching the exception if access is rejected.

Exceptions can also be used as a more general means of non-local transfer of control, even when an error is not at issue. For instance, the Mailman mailing list software, written in Python, uses exceptions to jump out of deeply nested message-handling logic when a decision has been made to reject a message or hold it for moderator approval.

Exceptions are often used as an alternative to the if-block, especially in threaded situations. A commonly invoked motto is EAFP, or "It is Easier to Ask for Forgiveness than Permission," which is attributed to Grace Hopper. The alternative, known as LBYL, or "Look Before You Leap", explicitly tests for pre-conditions.

In this first code sample, following the LBYL approach, there is an explicit check for the attribute before access:

defgetline() -> str: """Get one line from stdin and return it. """ return sys.stdin.readline()

Docstrings can be as large as the programmer wants and contain line breaks. In contrast with comments, docstrings are themselves Python objects and are part of the interpreted code that Python runs. That means that a running program can retrieve its own docstrings and manipulate that information, but the normal usage is to give other programmers information about how to invoke the object being documented in the docstring.

There are tools available that can extract the docstrings from Python code and generate documentation. Docstring documentation can also be accessed from the interpreter with the help() function, or from the shell with the pydoc command pydoc.

The doctest standard module uses interactions copied from Python shell sessions into docstrings to create tests, whereas the docopt module uses them to define command-line options.

Decorators

edit
@viking_chorus defmenu_item() -> None: print("spam")

is equivalent to

None:\n print(\"spam\")\nmenu_item = viking_chorus(menu_item)\n"}}'>defmenu_item() -> None: print("spam") menu_item = viking_chorus(menu_item)

Decorators are a form of metaprogramming; they enhance the action of the function or method they decorate. For example, in the sample below, viking_chorus might cause menu_item to be run 8 times (see Spam sketch) for each time it is called:

Callable[..., None]:\n def inner_func(*args: *tuple[Any, ...], **kwargs: Unpack[dict[str, Any]]) -> None:\n for i in range(8):\n myfunc(*args, **kwargs)\n return inner_func\n"}}'>R: TypeVar = TypeVar("R") defviking_chorus(myfunc: Callable[..., R]) -> Callable[..., None]: definner_func(*args: *tuple[Any, ...], **kwargs: Unpack[dict[str, Any]]) -> None: for i in range(8): myfunc(*args, **kwargs) return inner_func

Canonical uses of function decorators are for creating class methods or static methods, adding function attributes, tracing, setting pre- and postconditions, and synchronization, but can be used for far more, including tail recursion elimination, memoization and even improving the writing of other decorators.

Decorators can be chained by placing several on adjacent lines:

None:\n pass\n"}}'>@invincible @favourite_colour("Blue") defblack_knight() -> None: pass

is equivalent to

None:\n pass\nblack_knight = invincible(favourite_colour(\"Blue\")(black_knight))\n"}}'>defblack_knight() -> None: pass black_knight = invincible(favourite_colour("Blue")(black_knight))

or, using intermediate variables

None:\n pass\nblue_decorator = favourite_colour(\"Blue\")\ndecorated_by_blue = blue_decorator(black_knight)\nblack_knight = invincible(decorated_by_blue)\n"}}'>defblack_knight() -> None: pass blue_decorator = favourite_colour("Blue") decorated_by_blue = blue_decorator(black_knight) black_knight = invincible(decorated_by_blue)

In the example above, the favourite_colour decorator factory takes an argument. Decorator factories must return a decorator, which is then called with the object to be decorated as its argument:

Callable[[Callable[[], R]], Callable[[], R]]:\n def decorator(func: Callable[[], R]) -> Callable[[], R]:\n def wrapper() -> R:\n print(colour)\n func()\n return wrapper\n return decorator\n"}}'>deffavourite_colour(colour: str) -> Callable[[Callable[[], R]], Callable[[], R]]: defdecorator(func: Callable[[], R]) -> Callable[[], R]: defwrapper() -> R: print(colour) func() return wrapper return decorator

This would then decorate the black_knight function such that the colour, "Blue", would be printed prior to the black_knight function running. Closure ensures that the colour argument is accessible to the innermost wrapper function even when it is returned and goes out of scope, which is what allows decorators to work.

Despite the name, Python decorators are not an implementation of the decorator pattern. The decorator pattern is a design pattern used in statically-typed object-oriented programming languages to allow functionality to be added to objects at run time; Python decorators add functionality to functions and methods at definition time, and thus are a higher-level construct than decorator-pattern classes. The decorator pattern itself is trivially implementable in Python, because the language is duck typed, and so is not usually considered as such."2. Lexical analysis". Python 3 documentation. Python Software Foundation. Retrieved 2021-03-11.

  • ↑ "2. Lexical analysis". Python 3 documentation. Python Software Foundation. Retrieved 2022-01-22.
  • ↑ "6. Modules". The Python Tutorial. Python Software Foundation. Retrieved 25 October 2010.
  • ↑ Guido van Rossum (May 15, 2003). "Python main() functions". Archived from the original on July 11, 2015. Retrieved June 29, 2015,comments
  • ↑ Code Like a Pythonista: Idiomatic Python Archived 2014-05-27 at the Wayback Machine—on Python scripts used as modules
  • ↑ Hoffa, Felipe (2017-07-26). "400,000 GitHub repositories, 1 billion files, 14 terabytes of code: Spaces or Tabs?". Medium. Retrieved 2021-03-11.
  • ↑ "PEP 498 - Literal String Interpolation". What’s New In Python 3.6. 2016-12-23. Archived from the original on 2017-03-30. Retrieved 2017-03-29.
  • ↑ "6. Expressions — Python 3.9.2 documentation". docs.python.org. Retrieved 2021-03-17.
  • ↑ "Python 2.7.0 Release". Archived from the original on 2016-01-27. Retrieved 2016-01-19.
  • ↑ David Mertz. "Functional Programming in Python". IBM developerWorks. Archived from the original on 2007-02-20. Retrieved 2007-08-27.
  • ↑ "7. Simple statements § The global statement". Python 3.14.7 documentation. Python Software Foundation. 2026-09-01. Retrieved 2026-09-01.
  • ↑ "PEP 343 -- The "with" Statement". Archived from the original on 2014-12-14. Retrieved 2014-08-15.
  • ↑ Alex Martelli (19 May 2003). "EAFP v. LBYL". python-list mailing list. Retrieved 18 July 2011.{{cite web}}: CS1 maint: deprecated archival service (link)
  • ↑ cpython: The Python programming language, Python, 2017-10-15, archived from the original on 2017-09-15, retrieved 2017-10-15
  • ↑ Van Rossum, Guido. "The Python Tutorial". (written by the author of Python)

    View original on Wikipedia | Back | FazBrowse Home