Skip to content

Instantly share code, notes, and snippets.

@period331
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save period331/8746cd6eeef9b073ee12 to your computer and use it in GitHub Desktop.
Save period331/8746cd6eeef9b073ee12 to your computer and use it in GitHub Desktop.
meta class
# coding: utf-8
_STANDARDS = '__standards__'
class _StdData(type):
def __new__(mcs, name, bases, attrs):
super_new = super(_StdData, mcs).__new__
parents = [b for b in bases if isinstance(b, _StdData)]
if not parents:
return super_new(mcs, name, bases, attrs)
new_class = super_new(mcs, name, bases, attrs)
print(">>>>>>>", new_class, getattr(new_class, _STANDARDS), attrs, name, bases)
for attr, va in attrs.items():
if attr.startswith('_'):
continue
if callable(va):
continue
print('before<><><><>', new_class, getattr(new_class, _STANDARDS))
getattr(new_class, _STANDARDS)[attr] = va
print('after<><><><>', new_class, getattr(new_class, _STANDARDS))
return new_class
class StdData(object):
pass
StdData = _StdData('StdData', (StdData,), {_STANDARDS: dict()})
class A(StdData):
nameA = 'zhangming'
class B(StdData):
nameB = 'lisi'
if __name__ == '__main__':
b = B()
print(b), getattr(b, _STANDARDS)
@period331
Copy link
Author

output:

('>>>>>>>', <class '__main__.A'>, {}, {'__module__': '__main__', 'nameA': 'zhangming'}, 'A', (<class '__main__.StdData'>,))
('before<><><><>', <class '__main__.A'>, {})
('after<><><><>', <class '__main__.A'>, {'nameA': 'zhangming'})
('>>>>>>>', <class '__main__.B'>, {'nameA': 'zhangming'}, {'__module__': '__main__', 'nameB': 'lisi'}, 'B', (<class '__main__.StdData'>,))
('before<><><><>', <class '__main__.B'>, {'nameA': 'zhangming'})
('after<><><><>', <class '__main__.B'>, {'nameB': 'lisi', 'nameA': 'zhangming'})
<__main__.B object at 0x10e04af10> {'nameB': 'lisi', 'nameA': 'zhangming'}

@period331
Copy link
Author

我这里是想实现在import包的时候将class中的用户定义的属性保存在class中的__standards__属性中,供后面调用

@timonwong
Copy link

# coding: utf-8

_STANDARDS = '__standards__'


class _StdData(type):
    def __new__(mcs, name, bases, attrs):
        super_new = super(_StdData, mcs).__new__
        parents = [b for b in bases if isinstance(b, _StdData)]

        if not parents:
            return super_new(mcs, name, bases, attrs)

        new_class = super_new(mcs, name, bases, attrs)

        standards = {}
        for attr, va in attrs.items():
            if attr.startswith('_'):
                continue
            if callable(va):
                continue

            standards[attr] = va
        setattr(new_class, _STANDARDS, standards)
        return new_class


class StdData(object):
    pass

StdData = _StdData('StdData', (StdData,), {})

class A(StdData):
    nameA = 'zhangming'

class B(StdData):
    nameB = 'lisi'

if __name__ == '__main__':
    b = B()
    print(b, getattr(b, _STANDARDS))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment