In [1]:
from functools import wraps
import logging as Log
from inspect import Signature, Parameter
Log.basicConfig(format='%(asctime)s %(message)s', level=Log.INFO)
__author__ = 'chois'
In [29]:
"""
Node 为迭代对象
"""
class Node:
def __init__(self, value):
self._value = value
self._children = []
def __repr__(self):
return 'Node({!r})'.format(self._value)
def add_child(self, node):
self._children.append(node)
def __iter__(self):
return iter(self._children)
def depth_first(self):
return DepthFirstIterator(self)
class DepthFirstIterator(object):
'''
Depth-first traversal
'''
def __init__(self, start_node):
self._node = start_node
self._children_iter = None
self._child_iter = None
def __iter__(self):
Log.info(f'iter:{self._children_iter}')
return self
def __next__(self):
# Log.info(f'next---:{self._children_iter}')
# Return myself if just started; create an iterator for children
if self._children_iter is None:
self._children_iter = iter(self._node)
return self._node
# If processing a child, return its next item
elif self._child_iter is not None:
try:
nextchild = next(self._child_iter)
return nextchild
except StopIteration:
self._child_iter = None
return next(self)
# Advance to the next child and start its iteration
else:
self._child_iter = next(self._children_iter).depth_first()
return next(self)
In [30]:
root = Node(0)
child1 = Node(1)
child2 = Node(2)
root.add_child(child1)
root.add_child(child2)
child1.add_child(Node(3))
child1.add_child(Node(4))
child2.add_child(Node(5))
child2.add_child(Node(6))
child3.add_child(Node(7))
child3.add_child(Node(8))
In [31]:
for ch in root.depth_first():
Log.info(ch)
In [1]:
from functools import wraps
class Coordinate(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f'Coord: {self.__dict__}'
def check(func):
# functools.wraps 修饰器将func的func.__name__, func.__doc__等属性
# 添加到check属性中, 对_check函数的__name__, __doc__进行修饰
@wraps(func)
def _check(a, b):
# 对下文func调用的参数做提前预修饰
if a.x < 0 or a.y < 0:
a = Coordinate(a.x if a.x>0 else 0, a.y if a.y > 0 else 0)
if b.x < 0 or b.y < 0:
b = Coordinate(b.x if b.x>0 else 0, b.y if b.y > 0 else 0)
# func 的参数a, b 被上文修饰后传入func方法内部
ret = func(a, b)
# 判断输出结果的正负情况
if ret.x < 0 or ret.y < 0:
print('ret')
return Coordinate(ret.x if ret.x >0 else 0, ret.y if ret.y >0 else 0)
return ret
return _check
# 等效于 a, b 参数同时传递给 _check(a, b) 和 func(a, b)
# check(func)
# @check 修饰器运行路径: check -> _check(此处_check 方法完成对 func 函数参数修饰, 及调用) -> func -> add
# check ->{
# def _check():
# return _check
# }-> add/sub
@check
def add(x, y):
"""add doc"""
return Coordinate(x.x + y.x, x.y + y.y)
@check
def sub(x, y):
"""sub doc"""
return Coordinate(x.x - y.x, x.y - y.y)
one = Coordinate(100, 200)
tow = Coordinate(200, 300)
three = Coordinate(100, -100)
In [3]:
coord = add(one, tow); coord
# print(add.__name__, add.__doc__)
Out[3]:
In [15]:
coord1 = sub(tow, three); coord1
Out[15]:
In [109]:
class Fib(object):
def __init__(self, n):
self.a = 0
self.b = 1
self.end = n
def __iter__(self):
# con = 0
# con += 1
# Log.info('__iter__ at {!r}'.format(con))
return self
def __next__(self):
# con = 0
# con += 1
# Log.info('__next__ at {!r}'.format(con))
self.a, self.b = self.b, self.a + self.b
if self.a > self.end:
raise StopIteration();
else:
return self.a
def __repr__(self):
return 'fib {!r}'.format(self.a)
fb = Fib(5)
# iter(fb)
# for _ in fb:
# iter(fb)
# try:
for f in fb:
Log.info(f)
# except StopIteration:
# Log.info('end!')
In [28]:
class CP(object):
def __init__(self):
self.x = 0
pass
class C(CP):
@property
def xf(self):
"I am the 'x' property."
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def xf(self):
del self._x
c= C()
# c.x = 2
# c.x
# c.x
# del c.x
In [278]:
def f():
try:
yield 1
try:
yield 2
1 / 0
yield 3 # never get here
except ZeroDivisionError:
yield 4
yield 5
raise # reactivate last activate except t0 yield 8
except:
yield 6
yield 7 # the "raise" above stops this
except:
yield 8
yield 9
# ------------------------------------------
try:
x = 12
finally:
yield 10
yield 11
Log.info(list(f()))
In [3]:
# A binary tree class.
class Tree:
def __init__(self, label, left=None, right=None):
self.label = label
self.left = left
self.right = right
def __repr__(self, level=0, indent=" "):
s = level*indent + f'{self.label}'
if self.left:
s = s + "\n" + self.left.__repr__(level+1, indent)
if self.right:
s = s + "\n" + self.right.__repr__(level+1, indent)
return s
def __iter__(self):
return inorder(self)
# A recursive generator that generates Tree labels in in-order.
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
# Create a Tree from a list.
def tree(list):
n = len(list)
if n == 0:
return []
i = int(n / 2)
return Tree(list[i], tree(list[:i]), tree(list[i+1:]))
# Show it off: create a tree
t = tree("1234567")
list(t)
Out[3]:
In [33]:
class List(object):
def __init__(self, center, left: list=None, right: list=None):
self.center = center
self.left = left
self.right = right
def __iter__(self):
"""iterator """
return right_out(self)
def right_out(lst):
"""
generator
"""
# 二叉树算法
if lst:
for x in right_out(lst.right): # 右子树遍历,直至[]返回
yield x # 不会返回x
# 记录lst Node节点
yield lst.center
for x in right_out(lst.left): # 左子树遍历,直至[]返回
yield x #
def iter_tree(lst):
"""
生成可以迭代对象的迭代器
"""
n= len(lst)
if n == 0:
return []
i = int(n/2)
# Log.info('{}'.format(lst[i]))
# List实例初始化
return List(lst[i], iter_tree(lst[0:i]), iter_tree(lst[i+1:])) # 返回迭代对象
l_t = iter_tree([1,2,3,4,5,6,7,8])
for x in l_t:
Log.info(x)
In [40]:
'''
本例验证函数与方法的区别
概要:
1. 函数(function)是Python中一个可调用对象(callable), 方法(method)是一种和self实例绑定的函数为方法
2. 一个可调用对象是方法和函数,和这个对象无关,判断条件:是否与类或实例绑定(bound method)
3. 实例方法,在类中未和类绑定,是函数。在实例中,此实例方法与实例绑定,即变成方法
4. 静态方法没有和任何类或实例绑定,所以静态方法是个函数
5. 装饰器不会改变被装饰函数或方法的类型
6. 类实现__call__方法,其实例也不会变成方法或函数,依旧是类的实例
7. 使用callalble() 只能判断对象是否可调用,不能判断是不是函数或方法
8. 判断对象是函数或方法应该使用type(obj)
'''
def class_method_decorator(func):
"""
装饰器,测试使用,无功能
:param func:
:return:
"""
# Log.info(msg=inspect.getfullargspec(func).args)
if 'deg' in inspect.getfullargspec(func).args:
Log.info(msg='deg')
@wraps(func)
def wrapper(*args, deg=False, **kwargs):
if isinstance(args[0], TheClass):
if 'sum_self' in kwargs.keys():
Log.info(msg='func sum: {sum}'.format(sum=sum(kwargs['sum_self'])))
if args[0].__dict__:
Log.info(msg=f'self info: {args[0].__dict__}')
if deg:
Log.info(msg=f'debuging: {func.__name__}')
return func(*args)
sig = inspect.signature(func)
params = list(sig.parameters.values())
params.append(inspect.Parameter(
'deg',
inspect.Parameter.KEYWORD_ONLY,
default=False
))
wrapper.__signature__ = sig.replace(parameters=params)
return wrapper
def the_function():
"""
函数
:return:
"""
pass
def the_function():
"""
函数
:return:
"""
pass
class TheClass:
def __init__(self, a, b):
self.a = a
self.b = b
self.lst = set()
def __call__(self, *args, **kwargs):
""""""
for i in args:
self.lst.add(i)
return min(args)
def __len__(self):
return len(self.lst)
@classmethod
def class_method(cls):
"""
类方法
:return:
"""
pass
def instance_method(self):
"""
实例方法
"""
return self
@staticmethod
def static_method():
"""
静态方法
:return:
"""
pass
@class_method_decorator
def decorated_func(self, *args):
return (self.a + self.b) + sum(args)
the_class = TheClass(2, 3)
class_func = the_class.decorated_func(2, 4, deg=True, sum_self=[1, 2, 5, 1.666])
Log.info(msg=f'{type(the_class.decorated_func)}:{class_func}')
# Log.info('<info:{msg}> '.format(msg=the_class.decorated_func(deg=True)))
In [39]:
Log.info(inspect.Signature(the_class.decorated_func))