Understanding __init_subclass__

后端 未结 4 1566
甜味超标
甜味超标 2020-12-23 09:44

I finally upgraded my python version and I was discovering the new features added. Among other things, I was scratching my head around the new __init_subclass__ method. From

4条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-23 10:10

    PEP 487 sets out to take two common metaclass usecases and make them more accessible without having to understand all the ins and outs of metaclasses. The two new features, __init_subclass__ and __set_name__ are otherwise independent, they don't rely on one another.

    __init_subclass__ is just a hook method. You can use it for anything you want. It is useful for both registering subclasses in some way, and for setting default attribute values on those subclasses.

    We recently used this to provide 'adapters' for different version control systems, for example:

    class RepositoryType(Enum):
        HG = auto()
        GIT = auto()
        SVN = auto()
        PERFORCE = auto()
    
    class Repository():
        _registry = {t: {} for t in RepositoryType}
    
        def __init_subclass__(cls, scm_type=None, name=None, **kwargs):
            super().__init_subclass__(**kwargs)
            if scm_type is not None:
                cls._registry[scm_type][name] = cls
    
    class MainHgRepository(Repository, scm_type=RepositoryType.HG, name='main'):
        pass
    
    class GenericGitRepository(Repository, scm_type=RepositoryType.GIT):
        pass
    

    This trivially let us define handler classes for specific repositories without having to resort to using a metaclass or decorators.

提交回复
热议问题