Laurențiu Andronache
Laurențiu Andronache

Reputation: 584

How to created a delegated class instead of a subclass?

I tried to implement this tip https://docs.python.org/3/faq/programming.html#id55 in order to write some non-pythonic code, where I'd use a class with delegation (DelegatedLoanContract) instead of a subclass (LoanContract(ContractsWriter)). But I'm getting: TypeError: unsupported operand type(s) for +=: 'DelegatedLoanContract' and 'str'. Any idea how to solve it?

Here's the code: https://github.com/Laurentiu-Andronache/fun-with-delegation

Here's also a minimal version of the code:

class ContractsWriter:
    def __init__(self, signee_1, signee_2):
        self.signee_1 = signee_1
        self.signee_2 = signee_2
        self.contract_rules = []

    def __add__(self, other):
        if isinstance(other, str):
            self.contract_rules.append(other)
            return self
        elif isinstance(other, list):
            self.contract_rules.extend(other)
            return self
        else:
            raise NotImplemented('Invalid rule.')

class DelegatedLoanContract:
    def __init__(self, *args, **kwargs):
        self.__dict__['_contract'] = ContractsWriter(*args, **kwargs)
        self._contract.header = 'loan'

    def __getattr__(self, item):
        return getattr(self._contract, item)

    def __setattr__(self, key, value):
        setattr(self._contract, key, value)

if __name__ == '__main__':
    loan_contract = DelegatedLoanContract('Alan', 'John')
    loan_contract += 'Signee_1 will load 2,000 EUR to Signee_2.'

Upvotes: 1

Views: 56

Answers (1)

sanyassh
sanyassh

Reputation: 8550

If you are talking about delegation, you have to write __iadd__ method of DelegatedLoanContract that will delegate to __add__ method of ContractsWriter:

class DelegatedLoanContract:
    ... # your code here

    def __iadd__(self, other):
        self._contract += other
        return self

if __name__ == '__main__':
    loan_contract = DelegatedLoanContract('Alan', 'John')
    loan_contract += 'Signee_1 will load 2,000 EUR to Signee_2.'
    print(loan_contract._contract.contract_rules)
    # prints ['Signee_1 will load 2,000 EUR to Signee_2.']

Upvotes: 1

Related Questions