renumbering chapters >= 19
This commit is contained in:
50
24-class-metaprog/evaltime/builderlib.py
Normal file
50
24-class-metaprog/evaltime/builderlib.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# tag::BUILDERLIB_TOP[]
|
||||
print('@ builderlib module start')
|
||||
|
||||
class Builder: # <1>
|
||||
print('@ Builder body')
|
||||
|
||||
def __init_subclass__(cls): # <2>
|
||||
print(f'@ Builder.__init_subclass__({cls!r})')
|
||||
|
||||
def inner_0(self): # <3>
|
||||
print(f'@ SuperA.__init_subclass__:inner_0({self!r})')
|
||||
|
||||
cls.method_a = inner_0
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
print(f'@ Builder.__init__({self!r})')
|
||||
|
||||
|
||||
def deco(cls): # <4>
|
||||
print(f'@ deco({cls!r})')
|
||||
|
||||
def inner_1(self): # <5>
|
||||
print(f'@ deco:inner_1({self!r})')
|
||||
|
||||
cls.method_b = inner_1
|
||||
return cls # <6>
|
||||
# end::BUILDERLIB_TOP[]
|
||||
|
||||
# tag::BUILDERLIB_BOTTOM[]
|
||||
class Descriptor: # <1>
|
||||
print('@ Descriptor body')
|
||||
|
||||
def __init__(self): # <2>
|
||||
print(f'@ Descriptor.__init__({self!r})')
|
||||
|
||||
def __set_name__(self, owner, name): # <3>
|
||||
args = (self, owner, name)
|
||||
print(f'@ Descriptor.__set_name__{args!r}')
|
||||
|
||||
def __set__(self, instance, value): # <4>
|
||||
args = (self, instance, value)
|
||||
print(f'@ Descriptor.__set__{args!r}')
|
||||
|
||||
def __repr__(self):
|
||||
return '<Descriptor instance>'
|
||||
|
||||
|
||||
print('@ builderlib module end')
|
||||
# end::BUILDERLIB_BOTTOM[]
|
||||
30
24-class-metaprog/evaltime/evaldemo.py
Executable file
30
24-class-metaprog/evaltime/evaldemo.py
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from builderlib import Builder, deco, Descriptor
|
||||
|
||||
print('# evaldemo module start')
|
||||
|
||||
@deco # <1>
|
||||
class Klass(Builder): # <2>
|
||||
print('# Klass body')
|
||||
|
||||
attr = Descriptor() # <3>
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
print(f'# Klass.__init__({self!r})')
|
||||
|
||||
def __repr__(self):
|
||||
return '<Klass instance>'
|
||||
|
||||
|
||||
def main(): # <4>
|
||||
obj = Klass()
|
||||
obj.method_a()
|
||||
obj.method_b()
|
||||
obj.attr = 999
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
print('# evaldemo module end')
|
||||
33
24-class-metaprog/evaltime/evaldemo_meta.py
Executable file
33
24-class-metaprog/evaltime/evaldemo_meta.py
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from builderlib import Builder, deco, Descriptor
|
||||
from metalib import MetaKlass # <1>
|
||||
|
||||
print('# evaldemo_meta module start')
|
||||
|
||||
@deco
|
||||
class Klass(Builder, metaclass=MetaKlass): # <2>
|
||||
print('# Klass body')
|
||||
|
||||
attr = Descriptor()
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
print(f'# Klass.__init__({self!r})')
|
||||
|
||||
def __repr__(self):
|
||||
return '<Klass instance>'
|
||||
|
||||
|
||||
def main():
|
||||
obj = Klass()
|
||||
obj.method_a()
|
||||
obj.method_b()
|
||||
obj.method_c() # <3>
|
||||
obj.attr = 999
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
print('# evaldemo_meta module end')
|
||||
43
24-class-metaprog/evaltime/metalib.py
Normal file
43
24-class-metaprog/evaltime/metalib.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# tag::METALIB_TOP[]
|
||||
print('% metalib module start')
|
||||
|
||||
import collections
|
||||
|
||||
class NosyDict(collections.UserDict):
|
||||
def __setitem__(self, key, value):
|
||||
args = (self, key, value)
|
||||
print(f'% NosyDict.__setitem__{args!r}')
|
||||
super().__setitem__(key, value)
|
||||
|
||||
def __repr__(self):
|
||||
return '<NosyDict instance>'
|
||||
# end::METALIB_TOP[]
|
||||
|
||||
# tag::METALIB_BOTTOM[]
|
||||
class MetaKlass(type):
|
||||
print('% MetaKlass body')
|
||||
|
||||
@classmethod # <1>
|
||||
def __prepare__(meta_cls, cls_name, bases): # <2>
|
||||
args = (meta_cls, cls_name, bases)
|
||||
print(f'% MetaKlass.__prepare__{args!r}')
|
||||
return NosyDict() # <3>
|
||||
|
||||
def __new__(meta_cls, cls_name, bases, cls_dict): # <4>
|
||||
args = (meta_cls, cls_name, bases, cls_dict)
|
||||
print(f'% MetaKlass.__new__{args!r}')
|
||||
def inner_2(self):
|
||||
print(f'% MetaKlass.__new__:inner_2({self!r})')
|
||||
|
||||
cls = super().__new__(meta_cls, cls_name, bases, cls_dict.data) # <5>
|
||||
|
||||
cls.method_c = inner_2 # <6>
|
||||
|
||||
return cls # <7>
|
||||
|
||||
def __repr__(cls): # <8>
|
||||
cls_name = cls.__name__
|
||||
return f"<class {cls_name!r} built by MetaKlass>"
|
||||
|
||||
print('% metalib module end')
|
||||
# end::METALIB_BOTTOM[]
|
||||
Reference in New Issue
Block a user