This somewhat depends on what platform you are on. The most common way to do this is by printing ANSI escape sequences. For a simple example, here's some Python code from the Blender build scripts:
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
To use code like this, you can do something like:
print(bcolors.WARNING + "Warning: No active frommets remain. Continue?" + bcolors.ENDC)
Or, with Python 3.6+:
print(f"{bcolors.WARNING}Warning: No active frommets remain. Continue?{bcolors.ENDC}")
This will work on unixes including OS X, Linux and Windows (provided you use ANSICON, or in Windows 10 provided you enable VT100 emulation). There are ANSI codes for setting the color, moving the cursor, and more.
If you are going to get complicated with this (and it sounds like you are if you are writing a game), you should look into the "curses" module, which handles a lot of the complicated parts of this for you. The Python Curses HowTO is a good introduction.
If you are not using extended ASCII (i.e., not on a PC), you are stuck with the ASCII characters below 127, and '#' or '@' is probably your best bet for a block. If you can ensure your terminal is using a IBM extended ASCII character set, you have many more options. Characters 176, 177, 178 and 219 are the "block characters".
Some modern text-based programs, such as "Dwarf Fortress", emulate text mode in a graphical mode, and use images of the classic PC font. You can find some of these bitmaps that you can use on the Dwarf Fortress Wiki see (user-made tilesets).
The Text Mode Demo Contest has more resources for doing graphics in text mode.
figure
tells you the call signature:
from matplotlib.pyplot import figure
figure(figsize=(8, 6), dpi=80)
figure(figsize=(1,1))
would create an inch-by-inch image, which would be 80-by-80 pixels unless you also give a different dpi argument.
Best Answer
TL;DR: As of today (2019), in Python 3.7+ you must turn this feature on using a "future" statement,
from __future__ import annotations
.(The behaviour enabled by
from __future__ import annotations
might become the default in future versions of Python, and was going to be made the default in Python 3.10. However, the change in 3.10 was reverted at the last minute, and now may not happen at all.)In Python 3.6 or below, you should use a string.
I guess you got this exception:
This is because
Position
must be defined before you can use it in an annotation, unless you are using Python with PEP 563 changes enabled.Python 3.7+:
from __future__ import annotations
Python 3.7 introduces PEP 563: postponed evaluation of annotations. A module that uses the future statement
from __future__ import annotations
will store annotations as strings automatically:This had been scheduled to become the default in Python 3.10, but this change has now been postponed. Since Python still is a dynamically typed language so no type-checking is done at runtime, typing annotations should have no performance impact, right? Wrong! Before Python 3.7, the typing module used to be one of the slowest python modules in core so for code that involves importing the
typing
module, you will see an up to 7 times increase in performance when you upgrade to 3.7.Python <3.7: use a string
According to PEP 484, you should use a string instead of the class itself:
If you use the Django framework, this may be familiar, as Django models also use strings for forward references (foreign key definitions where the foreign model is
self
or is not declared yet). This should work with Pycharm and other tools.Sources
The relevant parts of PEP 484 and PEP 563, to spare you the trip:
and PEP 563:
Things that you may be tempted to do instead
A. Define a dummy
Position
Before the class definition, place a dummy definition:
This will get rid of the
NameError
and may even look OK:But is it?
B. Monkey-patch in order to add the annotations:
You may want to try some Python metaprogramming magic and write a decorator to monkey-patch the class definition in order to add annotations:
The decorator should be responsible for the equivalent of this:
At least it seems right:
Probably too much trouble.