Most of the explaination is coming from the references below. This is just a collection of refrances and thir comments to make it easy for me and for a python programmer to learn the consepts.
ContextLib: Descriptors: MetaClasses: Properties:
These are good references:
Example of a list comprehension:
>>> mylist = [num * num for num in range(3)] >>> for i in mylist: >>> print(i)
Problem with list is that it stores all the values in memory where as generator is store only the current value and iterate on the next value when called again. With Generator you don’t have history of old values.
>>> mygenerator = (num * num for num in range(3)) >>> for i in mygenerator: ... print(i)
This is an example of a generator comprehension inside a function that will return a generator:
def gen_square(nums): return (num * num for num in nums)
A function with a yield is a generator function. It returns a generator. It is not like return statment. It has diffrant behavior than return:
#!/usr/bin/env python def gen_square(nums): print('begin generator') for num in nums: yield num * num print('after generator') squares = gen_square([4, 2]) # create a generator print('made generator') for square in squares: print('control in caller') print(square)
Output would be:
made generator begin generator control in caller 16 after generator control in caller 4 after generator
When creating a generator no code will be run until you iterate over it and then it will reach yield and stop there and when called another time it will just read the code that is insie the loop until finished and then it will stop iteration.
>>> f = lambda x,y: x+y >>> f(1,2) 3
a = [1, 2] if 3 not in a: return False ====== a = [1, 2] assert 3 in a
- go test-race
A decorator is just a callable that takes a function as an argument and returns a replacement function. Reasons for using decorators:
- Flexible and generic
from functools import wraps def logged(func): @wraps(func) def with_logging(*args, **kwargs): print func.__name__ + " was called" return func(*args, **kwargs) return with_logging
class CustomOpen(object): def __init__(self, filename): self.file = open(filename) def __enter__(self): return self.file def __exit__(self, ctx_type, ctx_value, ctx_traceback): self.file.close() with CustomOpen('file') as f: contents = f.read()
from contextlib import contextmanager @contextmanager def custom_open(filename): f = open(filename) try: yield f finally: f.close() with custom_open('file') as f: contents = f.read()
- Understanding Python Decorators in 12 Easy Steps!
- Python Decorator Cheatsheet
- Implementing Decorators in Python
It is the ability of a program to examine the type or properties of an object at runtime. Example: dir(var), type(var) …