Python 3.9 ist da!

Gute Links und Tutorials könnt ihr hier posten.
Antworten
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ein paar neue Features:
  • Zugriff auf Zeitzonen durch das neue zoneinfo-Modul
  • Leichteres Zusammenführen von Wörterbüchern durch den Union-Operator (|)
  • Zusatzinfos bei Type-Hints nun möglich durch Annotated
  • Umstellung auf einen PEG-Parser (bisher wurde LL(1) genutzt) für weitere moderne Konstrukte in der Python-Syntax
  • Einführung von removeprefix() und removesuffix() für Strings
  • Nutzung von Builtin-Typen für Annotations (typing.List[int] -> list[int])
und vieles mehr

Eine ausführliche englische Beschreibung (dessen Übersicht ich als Vorlage genommen habe) findet sich hier:
https://realpython.com/python39-new-features/
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Eigentlich ist das unpassend im Offtopic-Forum. Könnte das jemand bitte nach "Links und Tutorials" verschieben...? :)
Benutzeravatar
DeaD_EyE
User
Beiträge: 1011
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Der neue Parser ermöglicht nun auch Syntax, der aufgrund des LL(1) parsers nicht möglich gewesen ist.

Code: Alles auswählen

from pathlib import Path

desktop = Path.home() / "Desktop"
file1 = desktop / "test_file_1.txt"
file2 = desktop / "test_file_2.txt"


with (
    file1.open("w") as fd1,
    file2.open("w") as fd2,
):
    fd1.write("Hello World 1\n")
    fd2.write("Hello World 2\n")
PS C:\Users\Admin\Desktop> py -3.8 .\peg_py.py
File ".\peg_py.py", line 9
file1.open("w") as fd1,
^
SyntaxError: invalid syntax
PS C:\Users\Admin\Desktop> py -3.9 .\peg_py.py
PS C:\Users\Admin\Desktop>
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
nezzcarth
User
Beiträge: 1631
Registriert: Samstag 16. April 2011, 12:47

Ich verstehe das Beispiel nicht so ganz. So geht es doch:

Code: Alles auswählen

In [20]: with f1.open('w') as file1, \
    ...:      f2.open('w') as file2:
    ...:     file1.write('a')
    ...:     file2.write('b')
Wäre das mit der Klammer wirklich "schöner"? Warum würde man diese Syntax haben wollen?
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Weil man \ nicht haben will. Da darf zum Beispiel kein „whitespace“ hinter stehen. An allen anderen Stellen kann man Klammern verwenden damit der Compiler weis, das der Ausdruck am Zeilenende noch nicht zu ende sein kann.

Edit: PEP 8 zu dem Thema:
The preferred way of wrapping long lines is by using Python’s implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation.
Als Beispiel für \ ist dann da auch ``with`` genannt, weil's nicht anders geht/ging.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das mit dem with-Mehrzeiler ist wohl auch eher als netter Nebeneffekt zu sehen. Als eine der nächsten großen Erweiterungen in der Python-Syntax ist jedenfalls das Pattern-Matching geplant mittels match-case Konstrukten. Dies war mit dem alten Parser nicht umsetzbar. Dementsprechend lautet auch die Aussage in PEP 622:
The match statement uses a soft keyword, and it is one of the first major Python features to take advantage of the capabilities of the new PEG parser.
Quelle: https://www.python.org/dev/peps/pep-062 ... arty-tools

Cython, PyPy und Konsorten werden jedenfalls ihren "Spaß" haben, wenn diese Neuerung kommt...
nezzcarth
User
Beiträge: 1631
Registriert: Samstag 16. April 2011, 12:47

@__blackjack__:
Okay. Danke für die Erklärung. Persönlich stört mich das \ nicht besonders, aber ist es gut, wenn die Syntax einheitlicher wird.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Übrigens, im selben PEP wird auch erklärt, was der wesentliche Unterschied durch die Nutzung als Soft Keyword ist:
The difference between hard and soft keywords is that hard keywords are always reserved words, even in positions where they make no sense (e.g. x = class + 1), while soft keywords only get a special meaning in context. Since PEP 617 the parser backtracks, that means that on different attempts to parse a code fragment it could interpret a soft keyword differently.

For example, suppose the parser encounters the following input:

Code: Alles auswählen

match [x, y]:
The parser first attempts to parse this as an expression statement. It interprets match as a NAME token, and then considers [x, y] to be a double subscript. It then encounters the colon and has to backtrack, since an expression statement cannot be followed by a colon. The parser then backtracks to the start of the line and finds that match is a soft keyword allowed in this position. It then considers [x, y] to be a list expression. The colon then is just what the parser expected, and the parse succeeds.
https://www.python.org/dev/peps/pep-062 ... patibility
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

PyPy ist ja gerade erst bei Python 3.7 als alpha-Version. Die haben noch Zeit. :-)

Interessanter wird das mit Softkeywords beim Syntaxhighlighting. Die Ansätze dort in den verschiedenen Editoren & Co sind wahrscheinlich nicht alle flexibel genug für so etwas.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
DeaD_EyE
User
Beiträge: 1011
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Habt ihr schon den TopologicalSorter ausprobiert?

Mit Graphen hab ich eigentlich nicht viel am Hut, habe dann aber ein Beispiel gesucht, wofür z.B. der TopologicalSorter nutzbar ist.
Ich hatte dann die Idee, dass man damit z.B. Abhängigkeiten auflösen kann, was ja apt-get und die anderen Paketmanager auch machen.

Code: Alles auswählen

import sys
from collections import defaultdict
from itertools import chain
from pprint import pprint
from subprocess import DEVNULL, CalledProcessError, check_output
from graphlib import TopologicalSorter


def get_deps(package):
    packages = []
    cmd = ("apt-cache", "depends", package)
    stdout = check_output(cmd, encoding="utf8", stderr=DEVNULL)
    try:
        for line in stdout.splitlines():
            if "Depends:" in line:
                _, p = line.split(":", maxsplit=1)
                if "<" in p:
                    continue
                packages.append(p.strip())
    except CalledProcessError:
        return []
    else:
        return packages


def main(p):
    deps = defaultdict(set)
    deps[p] = set(get_deps(p))
    while missing := (set(chain.from_iterable(deps.values())) - deps.keys()):
        for dep in missing:
            if dep not in deps:
                deps[dep] = set(get_deps(dep))
    # remove cyclic redundancies
    for name, p_deps in deps.items():
        for sub in p_deps:
            if sub in deps and name in deps[sub]:
                print("Removing:", name)
                deps[sub].remove(name)
    return dict(deps)


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(sys.executable, sys.argv[0], "package-name")
        sys.exit(1)
    package = sys.argv[1].strip().lower()
    deps = main(package)
    tps = TopologicalSorter(deps)
    tps.prepare()
    while tps.is_active():
        to_install = tps.get_ready()
        print(to_install)
        for install in to_install:
            tps.done(install)

andre@DESKTOP-F29NT09:/mnt/c/Users/Admin$ python dependencies2.py python3
Removing: libc6
Removing: libc6
('mime-support', 'libcrypt1', 'gcc-10-base')
('libgcc-s1',)
('libc6',)
('libdb5.3', 'libbz2-1.0', 'liblzma5', 'libexpat1', 'libsqlite3-0', 'libzstd1', 'libtinfo6', 'libffi7', 'libmpdec2', 'libuuid1', 'zlib1g', 'libacl1', 'libpcre2-8-0')
('libncursesw6', 'libselinux1')
('tar',)
('dpkg',)
('install-info', 'perl-base')
('readline-common', 'debconf')
('libreadline8', 'libssl1.1')
('libpython3.8-minimal',)
('python3.8-minimal', 'libpython3.8-stdlib')
('python3-minimal', 'python3.8', 'libpython3-stdlib')
('python3',)
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten