class Property:
    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel                                  # Zapisanie metod bez wiązania
        self.__doc__ = doc                                # lub innych obiektów wywoływalnych

    def __get__(self, instance, instancetype=None):
        if instance is None:
            return self
        if self.fget is None:
            raise AttributeError("nie można pobrać atrybutu")
        return self.fget(instance)                        # Przekazanie instancji do self
                                                          # w akcesorach właściwości
    def __set__(self, instance, value):
        if self.fset is None:
            raise AttributeError("nie można ustawić atrybutu")
        self.fset(instance, value)

    def __delete__(self, instance):
        if self.fdel is None:
            raise AttributeError("nie można usunąć atrybutu")
        self.fdel(instance)

class Person:
    def getName(self): 
        print('getName...')
    def setName(self, value): 
        print('setName...')
    name = Property(getName, setName)                     # Użyć jak property()

x = Person()
x.name
x.name = 'Robert'
del x.name

