import sections

In [1]:
from inspect import Signature, Parameter, signature
import logging as Log

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

__author__ = 'chois'

In [13]:
# Make a signature for a func(x, y=42, *, z=None)
parms = [ Parameter('x', Parameter.POSITIONAL_OR_KEYWORD),
        Parameter('y', Parameter.POSITIONAL_OR_KEYWORD, default=42),
        Parameter('z', Parameter.KEYWORD_ONLY, default=None) ]
sig = Signature(parms)

def func(*args, **kwargs):
    """func doc info"""
    bound_values = sig.bind(*args, **kwargs)
    for name, value in bound_values.arguments.items():
        print(name,value)
        
# d = {'clientip': '192.168.001.897', 'user': 'chois'}

# Log.warning(msg='out', extra=d)

In [10]:
def make_sig(*names):
    parms = [Parameter(name, Parameter.POSITIONAL_OR_KEYWORD)
            for name in names]
    return Signature(parms)

class Structure(object):
    __signature__ = make_sig()
    def __init__(self, *args, **kwargs):
        bound_values = self.__signature__.bind(*args, **kwargs)
        for name, value in bound_values.arguments.items():
            setattr(self, name, value)
            
# Example use
class Stock(Structure):
    __signature__ = make_sig('name', 'shares', 'price')

class Point(Structure):
    __signature__ = make_sig('x', 'y')
Log.info(msg=signature(Stock))

In [24]:
def make_sig(*names):
    parms = [Parameter(name, Parameter.POSITIONAL_OR_KEYWORD)
            for name in names]
    return Signature(parms)

class StructureMeta(type):
    def __new__(cls, clsname, bases, clsdict):
        Log.info(msg=f'new{cls,clsname, bases}')
        clsdict['__signature__'] = make_sig(*clsdict.get('_fields',[]))
        return super().__new__(cls, clsname, bases, clsdict)

class Structure(metaclass=StructureMeta):
    _fields = []
    def __init__(self, *args, **kwargs):
        bound_values = self.__signature__.bind(*args, **kwargs)
        for name, value in bound_values.arguments.items():
            setattr(self, name, value)

# Example
class Stock(Structure):
    _fields = ['name', 'shares', 'price']

class Point(Structure):
    _fields = ['x', 'y', 'z']
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
#         Log.info(type(self.__signature__))
#         pass
point_1= Point(1,2,3)
Log.info(msg=point_1.__dict__)


2017-09-11 10:02:23,557 new(<class '__main__.StructureMeta'>, 'Structure', ())
2017-09-11 10:02:23,560 new(<class '__main__.StructureMeta'>, 'Stock', (<class '__main__.Structure'>,))
2017-09-11 10:02:23,565 new(<class '__main__.StructureMeta'>, 'Point', (<class '__main__.Structure'>,))
2017-09-11 10:02:23,569 {'x': 1, 'y': 2, 'z': 3}