Python Tips
Tips you might not know
“%r” % anything
- Formating String
- print RAW data of object
- r means representation → repr
argv
- argument variable
Magic Method
class TestClass(object):
def __getattr__(self, k):
print "log: __getattr__"
print k
return k
test_class = TestClass()
print test_class.Test("HI")
can receive method(not existing in class) call by __getattr__ as string
(other magic methods: http://www.rafekettler.com/magicmethods.html)
Comparison Operators
- <> : !=
Performance Tips
- https://wiki.python.org/moin/PythonSpeed/PerformanceTips
- use append(item) instead of list.append
append = newlist.append
append(item)
Inheritance VS Composition
- ex) Composition
class Other(object):
def override(self):
print “OVERRIDE”class Child(object):
def __init__(self):
self.other = Other()
try-except
- It is recommended use try-except when catch module’s Exception
Decorator
A decorator is just a function that takes a function as an argument and returns a wrapped function.
def check_is_admin(f):
def wrapper(*args, **kwargs):
if kwargs.get('username') != 'admin':
raise Exception('This user is not allowed to access')
return f(*args, **kwargs)
return wrapper
@check_is_admin
Disadvantage
- Upper example’s function does not have docstring(__doc__), name(__name__)
- use functools.update_wrapper: copy functions references
@functools.wraps(f)
- inspect module
Can get function’s signature
import functools
import inspect
def check_is_admin(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
func_Args = inspect.getcallargs(f, *args, **kwargs)
if func_args.get('username') != 'admin':
raise Exception("This user is not allowed to access.")
return f(*args, **kwargs)
return wrapper
Method
Method is saved to class’s attribute
Basically, Class’s method is unbound(2.x)
You can create a instance of class using __self__ and also can make sure you pass a parameter value to the __self__.
staticmethod
Return a static method for function.
A static method does not receive an implicit first argument.
- can remove self from arguments
- Each time it is not necessary to instantiate a bound method to create the object.
- Bound methods also object so the cost of creating an object is generated.
classmethod
Methods that are bound to a Class
@classmethod
def get_radius(cls):
return cls.radius
- It is often used to create a factory method to create an object in a certain way.
- It is useful to create instance of class similar to __init__
Abstract Method
The method is defined in the parent class, but that may not have an actual method implementation.
@staticmethod
def get_radius():
raise NotImplementedError
abc module
import abcimport abcclass BestPizza(Pizza):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def get_ingredients(self):
“””return ingredients”””
Python is also possible to include the implementation of the code to abstract methods, unlike the other language. Also it is accessible to super.
super
Python has multiple inheritance is made possible from the very early stage of development.
mro()
Method resolution order, MRO
Descriptor Protocol
@property
Generator
- cf) expression is located next to the lambda.
- yield is the expression
- yield expression‘s value is None
- If the caller passes a value to yield the expression generator may have a value other than None. For this purpose, the generator provides a method called send ().
- next(g) is generator.send(None)
- The generator also provides methods throw () and close (), in addition to the send (). The purpose of these functions is entered in the generator because of the coroutine.
Functional standard functions
- map(function, iterable)
Call function using each item in the iterable.
Python 2.x will return a list as a result. Python 3.x will return a iterable map. - filter(function or None, iterable)
Filter iterable items based on function’s result.
Python 2.x will return a list as a result. Python 3.x will return a iterable map. - enumerate(iterable[, start])
return a iterable enumerate, this object yield tuple. - sorted(iterable, key=None, reverse=False)
return a sorted iterable. you can pass sorting function to key argument - any(iterable), all(iterable) are all return boolean based on iterable.
Useful in checking that values will meet all or any of conditions - zip(iter1, [,iter2 […]])
It is used to combine a number of list in the tuple.
It is useful to replace a pair of keys and values with the dictionary.
in Python 2.x: itertools.izip, itertools.imap, itertools.ifilter, etc. - functools.partial
Do not really allow changing the behavior of the function, the function is to create a wrapper function as a trick to change the factors that you need.
first([-1, 0, 1, 2], key=partial(greater_than, min=42))
AST(Abstract Syntax Tree)
- Any programming language represents an abstraction of the source code in a tree structure.
- Python also makes the AST parse the source files in the source.
https://docs.python.org/2/library/ast.html
Data Structure
Set
- you can use set’s functionality instead of nested for loop and if condition.
def has_invalid_fields(fields):
for field in fields:
if field not in [‘foo’, ‘bar’]:
return True
return False
def has_invalid_fields(fields):
return bool(set(fields) — set([‘foo’, ‘bar’])
collections.defaultdict
import collectionsdef add_animal_in_family(species, animal, family):
species[family].add(animal)
species = collections.defaultdict(set) # species = {}
add_animal_in_family(species, ‘cat’, ‘felidea’)
Profiling
- cProfile
- dis
https://docs.python.org/2/library/dis.html
def x():
return 42import dis
dis.dis(x)
Ordered List and bisect
- Ordered List: Can receive value in O(log n)
- bisection algorithm → https://docs.python.org/2/library/bisect.html
- bisect.bisect(list, item): returns an insertion point which comes after (to the right of) any existing entries of x in a.
(bisect.bisect, bisect.bisect_left, bisect.bisect_right) - bisect.insort(list, item): inserting x in a after any existing entries of x.
(bisect.insort, bisect.insort_left, bisect.insort_right)
Slots
Python objects are save all property to some dictionary
The purpose of __slots__ is to reduce the space in memory that each object instance takes up.
http://stackoverflow.com/questions/472000/python-slots
Named Tuple
foo_bar = collections.namedtuple(‘Foobar’, [‘x’, ‘y’])
with
http://effbot.org/zone/python-with-statement.htm
six
Python 2 and 3 compatibility utilities
https://pypi.python.org/pypi/six/
Long Text
Zen of python
class getattr, setattr
update python class’s attributes
- use setattr(model_instance, key, value)
plan = Plan.query.get(id)
for key, value in request.json.iteritems():
print setattr(plan, key, value)
Variable Reference
Best Practices
Pyenv
- http://blog.froehlichundfrei.de/2014/11/30/my-transition-to-python3-and-pyenv-goodby-virtualenvwrapper.html
- https://dobest.io/how-to-set-python-dev-env/ (korean)
Filter
Magic Method with __getattr__
class TestClass(object):
def __getattr__(self, k):
print "log: __getattr__"
print k
return k
test_class = TestClass()
print test_class.Test("HI")
using __getattr__ can receive method call not existing
http://www.rafekettler.com/magicmethods.html
Reduce visual noise with variable positional arguments
def log(message, values):
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print('%s: %s' % (message, values_str))
log('My numbers are', [1, 2])
log('Hi there', [])
>>>
My numbers are: 1, 2
Hi there
---------------------------------------------------------
def log(message, *values): # The only difference
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print('%s: %s' % (message, values_str))
log('My numbers are', 1, 2)
log('Hi there') # Much better
>>>
My numbers are: 1, 2
Hi there
- Functions can accept a variable number of positional arguments by using *args in thedef statement.
- You can use the items from a sequence as the positional arguments for a function with the *-operator.
- Using the *-operator with a generator may cause your program to run out of memory and crash.
- Adding new positional parameters to functions that accept *args can introduce hard-to-find bugs.
Argument Related
Default Argument Values
Unpacking Argument Lists
- *args: These arguments will be wrapped up in a tuple (v1, v2,)
- *-operator to unpack the arguments out of a list or tuple
- dictionaries can deliver keyword arguments with the **-operator
https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists - *name must occur before **name
- Positional arguments must be specified before keyword arguments.
remainder(number=20, 7)>>>
SyntaxError: non-keyword arg after keyword arg
Use None and Docstring to specify dynamic default arguments
def log(message, when=None):
"""Log a message with a timestamp.
Args:
message: Message to print.
when: datetime of when the message occurred.
Defaults to the present time.
"""
when = datetime.now() if when is None else when
print('%s: %s' % (when, message))
- Default arguments are only evaluated once: during function definition at module load time.
This can cause odd behaviors for dynamic values (like {} or []). - Use None as the default value for keyword arguments that have a dynamic value. Document the actual default behavior in the function’s docstring.
Python Logging
Logging related Tips
Python Subprocessing
from subprocess import callcall(‘ls’)call([‘ls’, ‘-al’])
Security Problem
- http://stackoverflow.com/questions/11679936/python-subprocess-arguments
- Also can use shell=True but not recommended due to security issue.
Python Standard Docstring
It will be continuously updated. Please send a feedback to me.