import sections

In [10]:
from functools import wraps
import logging as Log
from inspect import Signature, Parameter, getfullargspec, signature

Log.basicConfig(format='%(asctime)s %(message)s', level=Log.INFO)

*args, **kwargs


In [2]:
def kyword_only(x,**kwargs):
    print(x)
    for i in kwargs.items():
        print(i)
arg = {'c': 9, 'd': 10}
f_1 = kyword_only(2, **arg)


2
('c', 9)
('d', 10)

In [3]:
def deg_option(func):
    """
    """
    @wraps(func)
    def wrapper(*args, deg=False, **kwargs):
        
        if deg:
            print('calling, ', func.__name__)
        return func(*args)
    return wrapper

@deg_option
def my_sum(*arg):
    if arg:
        return max(arg)
    
args = [4, 8, 9, 11, 5]
f_2 = my_sum(*args, deg=True)
f_2


calling,  my_sum
Out[3]:
11

In [23]:
'''
本例验证函数与方法的区别
概要:
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 getfullargspec(func).args:
        Log.info(msg='deg')

    @wraps(func)
    def wrapper(cls, *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, **kwargs)

    sig = signature(func)
    params = list(sig.parameters.values())
    params.append(Parameter(
        'deg',
        Parameter.KEYWORD_ONLY,
        default=False
    ))
    wrapper.__signature__ = sig.replace(parameters=params)
    
    Log.info(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, **kwargs):
        
        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)))


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-23-7179d84d8589> in <module>()
     64 
     65 
---> 66 class TheClass:
     67 
     68     def __init__(self, a, b):

<ipython-input-23-7179d84d8589> in TheClass()
    103         pass
    104 
--> 105     @class_method_decorator
    106     def decorated_func(self, *args, **kwargs):
    107 

<ipython-input-23-7179d84d8589> in class_method_decorator(func)
     42         default=False
     43     ))
---> 44     wrapper.__signature__ = sig.replace(parameters=params)
     45 
     46     Log.info(params)

D:\Program Files\Python36\Lib\inspect.py in replace(self, parameters, return_annotation)
   2772 
   2773         return type(self)(parameters,
-> 2774                           return_annotation=return_annotation)
   2775 
   2776     def _hash_basis(self):

D:\Program Files\Python36\Lib\inspect.py in __init__(self, parameters, return_annotation, __validate_parameters__)
   2697                         msg = 'wrong parameter order: {!r} before {!r}'
   2698                         msg = msg.format(top_kind, kind)
-> 2699                         raise ValueError(msg)
   2700                     elif kind > top_kind:
   2701                         kind_defaults = False

ValueError: wrong parameter order: <_ParameterKind.VAR_KEYWORD: 4> before <_ParameterKind.KEYWORD_ONLY: 3>