Mastering Python Second Edition Release Code
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
Chapter 2, Pythonic Syntax
|
||||
##############################################################################
|
||||
|
||||
| Common Pitfalls and Style Guide explains what Pythonic code is and how to write code that is Pythonic and adheres to the Python philosophy.
|
||||
@@ -0,0 +1,78 @@
|
||||
# Simple formatting
|
||||
|
||||
>>> name = 'Rick'
|
||||
|
||||
>>> 'Hi %s' % name
|
||||
'Hi Rick'
|
||||
|
||||
>>> 'Hi {}'.format(name)
|
||||
'Hi Rick'
|
||||
|
||||
|
||||
>>> value = 1 / 3
|
||||
|
||||
>>> '%.2f' % value
|
||||
'0.33'
|
||||
|
||||
>>> '{:.2f}'.format(value)
|
||||
'0.33'
|
||||
|
||||
|
||||
>>> name = 'Rick'
|
||||
>>> value = 1 / 3
|
||||
|
||||
>>> 'Hi {0}, value: {1:.3f}. Bye {0}'.format(name, value)
|
||||
'Hi Rick, value: 0.333. Bye Rick'
|
||||
|
||||
|
||||
# Named variables
|
||||
|
||||
>>> name = 'Rick'
|
||||
|
||||
>>> 'Hi %(name)s' % dict(name=name)
|
||||
'Hi Rick'
|
||||
|
||||
>>> 'Hi {name}'.format(name=name)
|
||||
'Hi Rick'
|
||||
|
||||
>>> f'Hi {name}'
|
||||
'Hi Rick'
|
||||
|
||||
>>> 'Hi {name}'.format(**globals())
|
||||
'Hi Rick'
|
||||
|
||||
# Arbitrary expressions
|
||||
|
||||
## Accessing dict items
|
||||
|
||||
>>> username = 'wolph'
|
||||
>>> a = 123
|
||||
>>> b = 456
|
||||
>>> some_dict = dict(a=a, b=b)
|
||||
|
||||
>>> f'''a: {some_dict['a']}'''
|
||||
'a: 123'
|
||||
|
||||
>>> f'''sum: {some_dict['a'] + some_dict['b']}'''
|
||||
'sum: 579'
|
||||
|
||||
## Python expressions, specifically an inline if statement
|
||||
|
||||
>>> f'if statement: {a if a > b else b}'
|
||||
'if statement: 456'
|
||||
|
||||
## Function calls
|
||||
|
||||
>>> f'min: {min(a, b)}'
|
||||
'min: 123'
|
||||
|
||||
>>> f'Hi {username}. And in uppercase: {username.upper()}'
|
||||
'Hi wolph. And in uppercase: WOLPH'
|
||||
|
||||
## Loops
|
||||
|
||||
>>> f'Squares: {[x ** 2 for x in range(5)]}'
|
||||
'Squares: [0, 1, 4, 9, 16]'
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
>>> import this
|
||||
The Zen of Python, by Tim Peters
|
||||
<BLANKLINE>
|
||||
Beautiful is better than ugly.
|
||||
Explicit is better than implicit.
|
||||
Simple is better than complex.
|
||||
Complex is better than complicated.
|
||||
Flat is better than nested.
|
||||
Sparse is better than dense.
|
||||
Readability counts.
|
||||
Special cases aren't special enough to break the rules.
|
||||
Although practicality beats purity.
|
||||
Errors should never pass silently.
|
||||
Unless explicitly silenced.
|
||||
In the face of ambiguity, refuse the temptation to guess.
|
||||
There should be one-- and preferably only one --obvious way to do it.
|
||||
Although that way may not be obvious at first unless you're Dutch.
|
||||
Now is better than never.
|
||||
Although never is often better than *right* now.
|
||||
If the implementation is hard to explain, it's a bad idea.
|
||||
If the implementation is easy to explain, it may be a good idea.
|
||||
Namespaces are one honking great idea -- let's do more of those!
|
||||
@@ -0,0 +1,14 @@
|
||||
>>> filter_modulo = lambda i, m: (i[j] for j in \
|
||||
... range(len(i)) if i[j] % m)
|
||||
>>> list(filter_modulo(range(10), 2))
|
||||
[1, 3, 5, 7, 9]
|
||||
|
||||
|
||||
>>> def filter_modulo(items, modulo):
|
||||
... for item in items:
|
||||
... if item % modulo:
|
||||
... yield item
|
||||
...
|
||||
|
||||
>>> list(filter_modulo(range(10), 2))
|
||||
[1, 3, 5, 7, 9]
|
||||
@@ -0,0 +1,46 @@
|
||||
>>> from os import *
|
||||
>>> from asyncio import *
|
||||
|
||||
>>> assert wait
|
||||
|
||||
|
||||
|
||||
>>> from os import path
|
||||
>>> from asyncio import wait
|
||||
|
||||
>>> assert wait
|
||||
|
||||
|
||||
|
||||
>>> import os
|
||||
>>> import asyncio
|
||||
|
||||
>>> assert asyncio.wait
|
||||
>>> assert os.path
|
||||
|
||||
|
||||
>>> import concurrent.futures
|
||||
|
||||
>>> assert concurrent.futures.wait
|
||||
|
||||
|
||||
|
||||
>>> def spam(eggs, *args, **kwargs):
|
||||
... for arg in args:
|
||||
... eggs += arg
|
||||
... for extra_egg in kwargs.get('extra_eggs', []):
|
||||
... eggs += extra_egg
|
||||
... return eggs
|
||||
|
||||
>>> spam(1, 2, 3, extra_eggs=[4, 5])
|
||||
15
|
||||
|
||||
|
||||
>>> def sum_ints(*args):
|
||||
... total = 0
|
||||
... for arg in args:
|
||||
... total += arg
|
||||
... return total
|
||||
|
||||
>>> sum_ints(1, 2, 3, 4, 5)
|
||||
15
|
||||
@@ -0,0 +1,47 @@
|
||||
>>> import math
|
||||
>>> import itertools
|
||||
|
||||
>>> def primes_complicated():
|
||||
... sieved = dict()
|
||||
... i = 2
|
||||
...
|
||||
... while True:
|
||||
... if i not in sieved:
|
||||
... yield i
|
||||
... sieved[i * i] = [i]
|
||||
... else:
|
||||
... for j in sieved[i]:
|
||||
... sieved.setdefault(i + j, []).append(j)
|
||||
... del sieved[i]
|
||||
...
|
||||
... i += 1
|
||||
|
||||
>>> list(itertools.islice(primes_complicated(), 10))
|
||||
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
|
||||
|
||||
|
||||
>>> def primes_complex():
|
||||
... numbers = itertools.count(2)
|
||||
... while True:
|
||||
... yield (prime := next(numbers))
|
||||
... numbers = filter(prime.__rmod__, numbers)
|
||||
|
||||
>>> list(itertools.islice(primes_complex(), 10))
|
||||
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
|
||||
|
||||
>>> def is_prime(number):
|
||||
... if number == 0 or number == 1:
|
||||
... return False
|
||||
... for modulo in range(2, number):
|
||||
... if not number % modulo:
|
||||
... return False
|
||||
... else:
|
||||
... return True
|
||||
|
||||
>>> def primes_simple():
|
||||
... for i in itertools.count():
|
||||
... if is_prime(i):
|
||||
... yield i
|
||||
|
||||
>>> list(itertools.islice(primes_simple(), 10))
|
||||
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
|
||||
@@ -0,0 +1,27 @@
|
||||
>>> def between_and_modulo(value, a, b, modulo):
|
||||
... if value >= a:
|
||||
... if value <= b:
|
||||
... if value % modulo:
|
||||
... return True
|
||||
... return False
|
||||
|
||||
>>> for i in range(10):
|
||||
... if between_and_modulo(i, 2, 9, 2):
|
||||
... print(i, end=' ')
|
||||
3 5 7 9
|
||||
|
||||
|
||||
>>> def between_and_modulo(value, a, b, modulo):
|
||||
... if value < a:
|
||||
... return False
|
||||
... elif value > b:
|
||||
... return False
|
||||
... elif not value % modulo:
|
||||
... return False
|
||||
... else:
|
||||
... return True
|
||||
|
||||
>>> for i in range(10):
|
||||
... if between_and_modulo(i, 2, 9, 2):
|
||||
... print(i, end=' ')
|
||||
3 5 7 9
|
||||
@@ -0,0 +1,11 @@
|
||||
>>> f=lambda x:0**x or x*f(x-1)
|
||||
>>> f(40)
|
||||
815915283247897734345611269596115894272000000000
|
||||
|
||||
>>> def factorial(x):
|
||||
... if 0 ** x:
|
||||
... return 1
|
||||
... else:
|
||||
... return x * factorial(x - 1)
|
||||
>>> factorial(40)
|
||||
815915283247897734345611269596115894272000000000
|
||||
@@ -0,0 +1,32 @@
|
||||
>>> from functools import reduce
|
||||
|
||||
>>> fib=lambda n:n if n<2 else fib(n-1)+fib(n-2)
|
||||
>>> fib(10)
|
||||
55
|
||||
|
||||
>>> fib=lambda n:reduce(lambda x,y:(x[0]+x[1],x[0]),[(1,1)]*(n-1))[0]
|
||||
>>> fib(10)
|
||||
55
|
||||
|
||||
|
||||
>>> def fib(n):
|
||||
... if n < 2:
|
||||
... return n
|
||||
... else:
|
||||
... return fib(n - 1) + fib(n - 2)
|
||||
|
||||
>>> fib(10)
|
||||
55
|
||||
|
||||
|
||||
>>> def fib(n):
|
||||
... a = 0
|
||||
... b = 1
|
||||
... for _ in range(n):
|
||||
... a, b = b, a + b
|
||||
...
|
||||
... return a
|
||||
|
||||
>>> fib(10)
|
||||
55
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
>>> from concurrent.futures import ProcessPoolExecutor, \
|
||||
... CancelledError, TimeoutError
|
||||
|
||||
>>> from concurrent.futures import (
|
||||
... ProcessPoolExecutor, CancelledError, TimeoutError)
|
||||
|
||||
>>> from concurrent import futures
|
||||
|
||||
>>> from concurrent.futures.process import (
|
||||
... ProcessPoolExecutor
|
||||
... )
|
||||
|
||||
>>> from concurrent.futures import (
|
||||
... ProcessPoolExecutor,
|
||||
... CancelledError,
|
||||
... TimeoutError,
|
||||
... )
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
>>> some_user_input = '123abc'
|
||||
>>> try:
|
||||
... value = int(some_user_input)
|
||||
... except:
|
||||
... pass
|
||||
|
||||
|
||||
>>> some_user_input = '123abc'
|
||||
>>> try:
|
||||
... value = int(some_user_input)
|
||||
... except ValueError:
|
||||
... pass
|
||||
|
||||
|
||||
>>> import logging
|
||||
|
||||
>>> some_user_input = '123abc'
|
||||
>>> try:
|
||||
... value = int(some_user_input)
|
||||
... except Exception as exception:
|
||||
... logging.exception('Uncaught: {exception!r}')
|
||||
|
||||
|
||||
>>> some_user_input_a = '123'
|
||||
>>> some_user_input_b = 'abc'
|
||||
>>> try:
|
||||
... value = int(some_user_input_a)
|
||||
... value += int(some_user_input_b)
|
||||
... except:
|
||||
... value = 0
|
||||
|
||||
|
||||
>>> try:
|
||||
... 1 / 0 # Raises ZeroDivisionError
|
||||
... except ZeroDivisionError:
|
||||
... print('Got zero division error')
|
||||
... except Exception as exception:
|
||||
... print(f'Got unexpected exception: {exception}')
|
||||
... except BaseException as exception:
|
||||
... # Base exceptions are a special case for keyboard
|
||||
... # interrupts and a few other exceptions that are not
|
||||
... # technically errors.
|
||||
... print(f'Got base exception: {exception}')
|
||||
... else:
|
||||
... print('No exceptions happened, we can continue')
|
||||
... finally:
|
||||
... # Useful cleanup functions such as closing a file
|
||||
... print('This code is _always_ executed')
|
||||
Got zero division error
|
||||
This code is _always_ executed
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
>>> fh_a = open('spam', 'w', -1, None, None, '\n')
|
||||
>>> fh_b = open(file='spam', mode='w', buffering=-1, newline='\n')
|
||||
|
||||
>>> filename = 'spam'
|
||||
>>> mode = 'w'
|
||||
>>> buffers = -1
|
||||
>>> fh_b = open(filename, mode, buffers, newline='\n')
|
||||
@@ -0,0 +1,3 @@
|
||||
>>> import warnings
|
||||
|
||||
>>> warnings.warn('Something deprecated', DeprecationWarning)
|
||||
@@ -0,0 +1,9 @@
|
||||
>>> from json import loads
|
||||
|
||||
>>> loads('{}')
|
||||
{}
|
||||
|
||||
>>> import json
|
||||
|
||||
>>> json.loads('{}')
|
||||
{}
|
||||
@@ -0,0 +1,28 @@
|
||||
>>> timestamp = 12345
|
||||
>>> filename = f'{timestamp}.csv'
|
||||
|
||||
>>> import datetime
|
||||
|
||||
>>> timestamp = 12345
|
||||
|
||||
>>> if isinstance(timestamp, datetime.datetime):
|
||||
... filename = f'{timestamp}.csv'
|
||||
... else:
|
||||
... raise TypeError(f'{timestamp} is not a valid datetime')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: 12345 is not a valid datetime
|
||||
|
||||
|
||||
|
||||
>>> import datetime
|
||||
|
||||
>>> timestamp = datetime.date(2000, 10, 5)
|
||||
>>> filename = f'{timestamp}.csv'
|
||||
>>> print(f'Filename from date: {filename}')
|
||||
Filename from date: 2000-10-05.csv
|
||||
|
||||
>>> timestamp = '2000-10-05'
|
||||
>>> filename = f'{timestamp}.csv'
|
||||
>>> print(f'Filename from str: {filename}')
|
||||
Filename from str: 2000-10-05.csv
|
||||
@@ -0,0 +1,58 @@
|
||||
>>> a = 1
|
||||
>>> a == True
|
||||
True
|
||||
>>> a is True
|
||||
False
|
||||
|
||||
>>> b = 0
|
||||
>>> b == False
|
||||
True
|
||||
>>> b is False
|
||||
False
|
||||
|
||||
>>> def some_unsafe_function(arg=None):
|
||||
... if not arg:
|
||||
... arg = 123
|
||||
...
|
||||
... return arg
|
||||
|
||||
>>> some_unsafe_function(0)
|
||||
123
|
||||
>>> some_unsafe_function(None)
|
||||
123
|
||||
|
||||
|
||||
>>> def some_safe_function(arg=None):
|
||||
... if arg is None:
|
||||
... arg = 123
|
||||
...
|
||||
... return arg
|
||||
|
||||
>>> some_safe_function(0)
|
||||
0
|
||||
>>> some_safe_function(None)
|
||||
123
|
||||
|
||||
|
||||
>>> a = 200 + 56
|
||||
>>> b = 256
|
||||
>>> c = 200 + 57
|
||||
>>> d = 257
|
||||
|
||||
>>> a == b
|
||||
True
|
||||
>>> a is b
|
||||
True
|
||||
>>> c == d
|
||||
True
|
||||
>>> c is d
|
||||
False
|
||||
|
||||
|
||||
>>> spam = list(range(1000000))
|
||||
>>> eggs = list(range(1000000))
|
||||
|
||||
>>> spam == eggs
|
||||
True
|
||||
>>> spam is eggs
|
||||
False
|
||||
@@ -0,0 +1,21 @@
|
||||
>>> my_range = range(5)
|
||||
>>> i = 0
|
||||
>>> while i < len(my_range):
|
||||
... item = my_range[i]
|
||||
... print(i, item, end=', ')
|
||||
... i += 1
|
||||
0 0, 1 1, 2 2, 3 3, 4 4,
|
||||
|
||||
|
||||
>>> my_range = range(5)
|
||||
>>> for item in my_range:
|
||||
... print(item, end=', ')
|
||||
0, 1, 2, 3, 4,
|
||||
|
||||
>>> for i, item in enumerate(my_range):
|
||||
... print(i, item, end=', ')
|
||||
0 0, 1 1, 2 2, 3 3, 4 4,
|
||||
|
||||
>>> my_range = range(5)
|
||||
>>> [(i, item) for i, item in enumerate(my_range)]
|
||||
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
|
||||
@@ -0,0 +1,18 @@
|
||||
def noop():
|
||||
pass
|
||||
|
||||
|
||||
def yield_cube_points(matrix):
|
||||
for x in matrix:
|
||||
for y in x:
|
||||
for z in y:
|
||||
yield (x, y, z)
|
||||
|
||||
|
||||
def print_cube(matrix):
|
||||
for x in matrix:
|
||||
for y in x:
|
||||
for z in y:
|
||||
print(z, end='')
|
||||
print()
|
||||
print()
|
||||
@@ -0,0 +1,2 @@
|
||||
some_number: int
|
||||
some_number = 'test'
|
||||
@@ -0,0 +1,2 @@
|
||||
def spam(a,b,c):print(a,b+c)
|
||||
def eggs():pass
|
||||
@@ -0,0 +1,182 @@
|
||||
>>> some_variable = 123
|
||||
|
||||
>>> match some_variable:
|
||||
... case 1:
|
||||
... print('Got 1')
|
||||
... case 2:
|
||||
... print('Got 2')
|
||||
... case _:
|
||||
... print('Got something else')
|
||||
Got something else
|
||||
|
||||
>>> if some_variable == 1:
|
||||
... print('Got 1')
|
||||
... elif some_variable == 1:
|
||||
... print('Got 2')
|
||||
... else:
|
||||
... print('Got something else')
|
||||
Got something else
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> some_variable = 123
|
||||
|
||||
>>> match some_variable:
|
||||
... case 1:
|
||||
... print('Got 1')
|
||||
... case other:
|
||||
... print('Got something else:', other)
|
||||
Got something else: 123
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> class Direction:
|
||||
... LEFT = -1
|
||||
... RIGHT = 1
|
||||
|
||||
>>> some_variable = Direction.LEFT
|
||||
|
||||
>>> match some_variable:
|
||||
... case Direction.LEFT:
|
||||
... print('Going left')
|
||||
... case Direction.RIGHT:
|
||||
... print('Going right')
|
||||
Going left
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> class Direction:
|
||||
... LEFT = -1
|
||||
... UP = 0
|
||||
... RIGHT = 1
|
||||
... DOWN = 2
|
||||
|
||||
>>> some_variable = Direction.LEFT
|
||||
|
||||
>>> match some_variable:
|
||||
... case Direction.LEFT | Direction.RIGHT:
|
||||
... print('Going horizontal')
|
||||
... case Direction.UP | Direction.DOWN:
|
||||
... print('Going vertical')
|
||||
Going horizontal
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> values = -1, 0, 1
|
||||
>>> for value in values:
|
||||
... print('matching', value, end=': ')
|
||||
... match value:
|
||||
... case negative if negative < 0:
|
||||
... print(f'{negative} is smaller than 0')
|
||||
... case positive if positive > 0:
|
||||
... print(f'{positive} is greater than 0')
|
||||
... case _:
|
||||
... print('no match')
|
||||
matching -1: -1 is smaller than 0
|
||||
matching 0: no match
|
||||
matching 1: 1 is greater than 0
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> values = (0, 1), (0, 2), (1, 2)
|
||||
>>> for value in values:
|
||||
... print('matching', value, end=': ')
|
||||
... match value:
|
||||
... case 0, 1:
|
||||
... print('exactly matched 0, 1')
|
||||
... case 0, y:
|
||||
... print(f'matched 0, y with y: {y}')
|
||||
... case x, y:
|
||||
... print(f'matched x, y with x, y: {x}, {y}')
|
||||
matching (0, 1): exactly matched 0, 1
|
||||
matching (0, 2): matched 0, y with y: 2
|
||||
matching (1, 2): matched x, y with x, y: 1, 2
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> def get_uri(*args):
|
||||
... # Set defaults so we only have to store changed variables
|
||||
... protocol, port, paths = 'https', 443, ()
|
||||
... match args:
|
||||
... case (hostname,):
|
||||
... pass
|
||||
... case (hostname, port):
|
||||
... pass
|
||||
... case (hostname, port, protocol, *paths):
|
||||
... pass
|
||||
... case _:
|
||||
... raise RuntimeError(f'Invalid arguments {args}')
|
||||
...
|
||||
... path = '/'.join(paths)
|
||||
... return f'{protocol}://{hostname}:{port}/{path}'
|
||||
|
||||
>>> get_uri('localhost')
|
||||
'https://localhost:443/'
|
||||
>>> get_uri('localhost', 12345)
|
||||
'https://localhost:12345/'
|
||||
>>> get_uri('localhost', 80, 'http')
|
||||
'http://localhost:80/'
|
||||
>>> get_uri('localhost', 80, 'http', 'some', 'paths')
|
||||
'http://localhost:80/some/paths'
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> values = (0, 1), (0, 2), (1, 2)
|
||||
>>> for value in values:
|
||||
... print('matching', value, end=': ')
|
||||
... match value:
|
||||
... case 0 as x, (1 | 2) as y:
|
||||
... print(f'matched x, y with x, y: {x}, {y}')
|
||||
... case _:
|
||||
... print('no match')
|
||||
matching (0, 1): matched x, y with x, y: 0, 1
|
||||
matching (0, 2): matched x, y with x, y: 0, 2
|
||||
matching (1, 2): no match
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> values = dict(a=0, b=0), dict(a=0, b=1), dict(a=1, b=1)
|
||||
>>> for value in values:
|
||||
... print('matching', value, end=': ')
|
||||
... match value:
|
||||
... case {'a': 0}:
|
||||
... print('matched a=0:', value)
|
||||
... case {'a': 0, 'b': 0}:
|
||||
... print('matched a=0, b=0:', value)
|
||||
... case _:
|
||||
... print('no match')
|
||||
matching {'a': 0, 'b': 0}: matched a=0: {'a': 0, 'b': 0}
|
||||
matching {'a': 0, 'b': 1}: matched a=0: {'a': 0, 'b': 1}
|
||||
matching {'a': 1, 'b': 1}: no match
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> class Person:
|
||||
... def __init__(self, name):
|
||||
... self.name = name
|
||||
|
||||
>>> values = Person('Rick'), Person('Guido')
|
||||
>>> for value in values:
|
||||
... match value:
|
||||
... case Person(name='Rick'):
|
||||
... print('I found Rick')
|
||||
... case Person(occupation='Programmer'):
|
||||
... print('I found a programmer')
|
||||
... case Person() as person:
|
||||
... print('I found a person:', person.name)
|
||||
I found Rick
|
||||
I found a person: Guido
|
||||
|
||||
##################################################################
|
||||
|
||||
>>> class Person:
|
||||
... def __init__(self, name):
|
||||
... self.name = name
|
||||
|
||||
>>> value = Person(123)
|
||||
>>> match value:
|
||||
... case Person(name=str() as name):
|
||||
... print('Found person with str name:', name)
|
||||
... case Person(name=int() as name):
|
||||
... print('Found person with int name:', name)
|
||||
Found person with int name: 123
|
||||
@@ -0,0 +1,18 @@
|
||||
>>> g = 1
|
||||
>>> def print_global():
|
||||
... print(f'Value: {g}')
|
||||
|
||||
>>> print_global()
|
||||
Value: 1
|
||||
|
||||
>>> g = 1
|
||||
|
||||
>>> def print_global():
|
||||
... g += 1
|
||||
... print(f'Value: {g}')
|
||||
|
||||
>>> print_global()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
UnboundLocalError: local variable 'g' referenced before assignment
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
>>> import copy
|
||||
|
||||
>>> x = [[1], [2, 3]]
|
||||
>>> y = x.copy()
|
||||
>>> z = copy.deepcopy(x)
|
||||
|
||||
>>> x.append('a')
|
||||
>>> x[0].append(x)
|
||||
|
||||
>>> x
|
||||
[[1, [...]], [2, 3], 'a']
|
||||
>>> y
|
||||
[[1, [...]], [2, 3]]
|
||||
>>> z
|
||||
[[1], [2, 3]]
|
||||
|
||||
|
||||
>>> def append(list_=[], value='value'):
|
||||
... list_.append(value)
|
||||
... return list_
|
||||
|
||||
>>> append(value='a')
|
||||
['a']
|
||||
>>> append(value='b')
|
||||
['a', 'b']
|
||||
|
||||
|
||||
>>> def append(list_=None, value='value'):
|
||||
... if list_ is None:
|
||||
... list_ = []
|
||||
... list_.append(value)
|
||||
... return list_
|
||||
|
||||
>>> append(value='a')
|
||||
['a']
|
||||
>>> append(value='b')
|
||||
['b']
|
||||
@@ -0,0 +1,47 @@
|
||||
>>> class SomeClass:
|
||||
... class_list = []
|
||||
...
|
||||
... def __init__(self):
|
||||
... self.instance_list = []
|
||||
|
||||
>>> SomeClass.class_list.append('from class')
|
||||
>>> instance = SomeClass()
|
||||
>>> instance.class_list.append('from instance')
|
||||
>>> instance.instance_list.append('from instance')
|
||||
|
||||
>>> SomeClass.class_list
|
||||
['from class', 'from instance']
|
||||
>>> SomeClass.instance_list
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: ... 'SomeClass' has no attribute 'instance_list'
|
||||
|
||||
>>> instance.class_list
|
||||
['from class', 'from instance']
|
||||
>>> instance.instance_list
|
||||
['from instance']
|
||||
|
||||
|
||||
>>> class Parent:
|
||||
... pass
|
||||
|
||||
|
||||
>>> class Child(Parent):
|
||||
... pass
|
||||
|
||||
|
||||
>>> Parent.parent_property = 'parent'
|
||||
>>> Child.parent_property
|
||||
'parent'
|
||||
|
||||
>>> Child.parent_property = 'child'
|
||||
>>> Parent.parent_property
|
||||
'parent'
|
||||
>>> Child.parent_property
|
||||
'child'
|
||||
|
||||
>>> Child.child_property = 'child'
|
||||
>>> Parent.child_property
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: ... 'Parent' has no attribute 'child_property'
|
||||
@@ -0,0 +1,32 @@
|
||||
import builtins
|
||||
import inspect
|
||||
import pprint
|
||||
import re
|
||||
|
||||
|
||||
def pp(*args, **kwargs):
|
||||
'''PrettyPrint function that prints the variable name when
|
||||
available and pprints the data
|
||||
|
||||
>>> x = 10
|
||||
>>> pp(x)
|
||||
# x: 10
|
||||
'''
|
||||
# Fetch the current frame from the stack
|
||||
frame = inspect.currentframe().f_back
|
||||
# Prepare the frame info
|
||||
frame_info = inspect.getframeinfo(frame)
|
||||
|
||||
# Walk through the lines of the function
|
||||
for line in frame_info[3]:
|
||||
# Search for the pp() function call with a fancy regexp
|
||||
m = re.search(r'\bpp\s*\(\s*([^)]*)\s*\)', line)
|
||||
if m:
|
||||
print('# %s:' % m.group(1), end=' ')
|
||||
break
|
||||
|
||||
pprint.pprint(*args, **kwargs)
|
||||
|
||||
|
||||
builtins.pf = pprint.pformat
|
||||
builtins.pp = pp
|
||||
@@ -0,0 +1,14 @@
|
||||
>>> list = list((1, 2, 3))
|
||||
>>> list
|
||||
[1, 2, 3]
|
||||
|
||||
>>> list((4, 5, 6))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: 'list' object is not callable
|
||||
|
||||
>>> import = 'Some import'
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: invalid syntax
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
>>> dict_ = dict(a=123)
|
||||
>>> set_ = set((456,))
|
||||
|
||||
>>> for key in dict_:
|
||||
... del dict_[key]
|
||||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
RuntimeError: dictionary changed size during iteration
|
||||
|
||||
>>> for item in set_:
|
||||
... set_.remove(item)
|
||||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
RuntimeError: Set changed size during iteration
|
||||
|
||||
|
||||
>>> list_ = list(range(10))
|
||||
>>> list_
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
>>> for item in list_:
|
||||
... print(list_.pop(0), end=', ')
|
||||
0, 1, 2, 3, 4,
|
||||
|
||||
>>> list_
|
||||
[5, 6, 7, 8, 9]
|
||||
|
||||
|
||||
>>> list_ = list(range(10))
|
||||
|
||||
>>> for item in list(list_):
|
||||
... print(list_.pop(0), end=', ')
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
@@ -0,0 +1,20 @@
|
||||
>>> exception = None
|
||||
|
||||
>>> try:
|
||||
... 1 / 0
|
||||
... except ZeroDivisionError as exception:
|
||||
... pass
|
||||
|
||||
>>> exception
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
NameError: name 'exception' is not defined
|
||||
|
||||
|
||||
>>> try:
|
||||
... 1 / 0
|
||||
... except ZeroDivisionError as exception:
|
||||
... new_exception = exception
|
||||
|
||||
>>> new_exception
|
||||
ZeroDivisionError('division by zero')
|
||||
@@ -0,0 +1,14 @@
|
||||
>>> functions = [lambda: i for i in range(3)]
|
||||
|
||||
>>> for function in functions:
|
||||
... print(function(), end=', ')
|
||||
2, 2, 2,
|
||||
|
||||
|
||||
>>> from functools import partial
|
||||
|
||||
>>> functions = [partial(lambda x: x, i) for i in range(3)]
|
||||
|
||||
>>> for function in functions:
|
||||
... print(function(), end=', ')
|
||||
0, 1, 2,
|
||||
@@ -0,0 +1,9 @@
|
||||
import T_28_circular_imports_b
|
||||
|
||||
|
||||
class FileA:
|
||||
pass
|
||||
|
||||
|
||||
class FileC(T_28_circular_imports_b.FileB):
|
||||
pass
|
||||
@@ -0,0 +1,5 @@
|
||||
import T_28_circular_imports_a
|
||||
|
||||
|
||||
class FileB(T_28_circular_imports_a.FileA):
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
class FileA:
|
||||
pass
|
||||
@@ -0,0 +1,5 @@
|
||||
import T_29_circular_imports_a
|
||||
|
||||
|
||||
class FileB(T_29_circular_imports_a.FileA):
|
||||
pass
|
||||
@@ -0,0 +1,5 @@
|
||||
import T_29_circular_imports_b
|
||||
|
||||
|
||||
class FileC(T_29_circular_imports_b.FileB):
|
||||
pass
|
||||
@@ -0,0 +1,10 @@
|
||||
>>> import importlib
|
||||
|
||||
>>> module_name = 'sys'
|
||||
>>> attribute = 'version_info'
|
||||
|
||||
>>> module = importlib.import_module(module_name)
|
||||
>>> module
|
||||
<module 'sys' (built-in)>
|
||||
>>> getattr(module, attribute).major
|
||||
3
|
||||
@@ -0,0 +1,7 @@
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
# Little hack to add the current directory to sys.path so we can
|
||||
# find the imports
|
||||
path = pathlib.Path(__file__).parent
|
||||
sys.path.append(str(path.resolve()))
|
||||
Reference in New Issue
Block a user