Skip to content

Instantly share code, notes, and snippets.

@GuangTianLi
Last active February 3, 2019 04:47
Show Gist options
  • Save GuangTianLi/34aeb2c1460ef3289a3a2420e2a04168 to your computer and use it in GitHub Desktop.
Save GuangTianLi/34aeb2c1460ef3289a3a2420e2a04168 to your computer and use it in GitHub Desktop.
Type hint with dynamic __init__.
from dataclasses import dataclass
from typing import Tuple, Dict, TypeVar
_C = TypeVar('_C', bound=type)
class TestORM(type):
def __new__(cls, clsname: str, bases: Tuple, clsdict: Dict):
param = ""
for key, key_type in clsdict.get('__annotations__', {}).items():
param += f", {key}: {key_type.__name__} = {clsdict.get(key)}"
clsdict['__init__'] = make_init(param)
return super().__new__(cls, clsname, bases, clsdict)
@dataclass
class Test:
a: int = 0
def mydataclass(cls: _C) -> _C:
param = ""
for key, key_type in cls.__annotations__.items():
param += f", {key}: {key_type.__name__} = {getattr(cls, key)}"
setattr(cls, "__init__", make_init(param))
return cls
def make_init(param:str):
locals = {}
txt = f'def __init__(self{param}):\n pass'
exec(txt, None, locals)
return locals['__init__']
@mydataclass
class MyTest:
a: int = 0
class MyORMTest(metaclass=TestORM):
a: int = 0
if __name__ == '__main__':
Test(a='a')
MyTest(a='a')
MyORMTest(a='a')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment