What are some (concrete) use-cases for metaclasses?

前端 未结 19 1115
悲&欢浪女
悲&欢浪女 2020-12-07 06:51

I have a friend who likes to use metaclasses, and regularly offers them as a solution.

I am of the mind that you almost never need to use metaclasses. Why? because I

19条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-07 07:31

    I recently had to use a metaclass to help declaratively define an SQLAlchemy model around a database table populated with U.S. Census data from http://census.ire.org/data/bulkdata.html

    IRE provides database shells for the census data tables, which create integer columns following a naming convention from the Census Bureau of p012015, p012016, p012017, etc.

    I wanted to a) be able to access these columns using a model_instance.p012017 syntax, b) be fairly explicit about what I was doing and c) not have to explicitly define dozens of fields on the model, so I subclassed SQLAlchemy's DeclarativeMeta to iterate through a range of the columns and automatically create model fields corresponding to the columns:

    from sqlalchemy.ext.declarative.api import DeclarativeMeta
    
    class CensusTableMeta(DeclarativeMeta):
        def __init__(cls, classname, bases, dict_):
            table = 'p012'
            for i in range(1, 49):
                fname = "%s%03d" % (table, i)
                dict_[fname] = Column(Integer)
                setattr(cls, fname, dict_[fname])
    
            super(CensusTableMeta, cls).__init__(classname, bases, dict_)
    

    I could then use this metaclass for my model definition and access the automatically enumerated fields on the model:

    CensusTableBase = declarative_base(metaclass=CensusTableMeta)
    
    class P12Tract(CensusTableBase):
        __tablename__ = 'ire_p12'
    
        geoid = Column(String(12), primary_key=True)
    
        @property
        def male_under_5(self):
            return self.p012003
    
        ...
    

提交回复
热议问题