# Rejestrowanie udekorowanych obiektów w API
from __future__ import print_function # 2.X

registry = {}
def register(obj):                          # Zarówno aklasa, jak dekorator funkcji
    registry[obj.__name__] = obj            # Dodanie do rejestru
    return obj                              # Zwrócenie samego obiektu, a klasy opakowującej

@register
def hack(x):
    return(x ** 2)                          # hack = register(hack)

@register
def app(x):
    return(x ** 3)

@register
class Code:                                 # Code = register(Code)
    def __init__(self, x):
        self.data = x ** 4
    def __str__(self):
        return str(self.data)

print('Rejestr:')
for name in registry:
    print(name, '=>', registry[name], type(registry[name]))

print('\nWywołania ręczne:')
print(hack(2))                              # Ręczne wywołanie obiektów
print(app(2))                               # Późniejsze wwołania nieprzechwycone
X = Code(2)
print(X)

print('\nWywołania rejestru:')
for name in registry:
    print(name, '=>', registry[name](2))    # Wywołanie z rejestru


"""
Rejestr:
hack => <function hack at 0x10bf78fe0> <class 'function'>
app => <function app at 0x10bf79080> <class 'function'>
Code => <class '__main__.Code'> <class 'type'>

Wywołania ręczne:
4
8
16

Wywołania rejestru:
hack => 4
app => 8
Code => 16
"""
