File: LP6E/Chapter30/contains.py

def trace(msg, end=''):
    print(f'{msg} ', end=end)                 # print sans newline

class Iters:
    def __init__(self, value):
        self.data = value

    def __getitem__(self, i):                 # Fallback for iteration
        trace(f'@get[{i}]')                   # Also for index, slice
        return self.data[i]

    def __iter__(self):                       # Preferred for iteration
        trace('@iter')                        # Allows only one active iterator
        self.ix = 0
        return self

    def __next__(self):
        trace('@next')
        if self.ix == len(self.data): raise StopIteration
        item = self.data[self.ix]
        self.ix += 1
        return item

    def __contains__(self, x):                # Preferred for 'in' membership
        trace('@contains')
        return x in self.data

def self_test(Iters):
    X = Iters([1, 2, 3, 4])                            # Make one instance
    tests = 'In', 'For', 'Comp', 'Map', 'Manual'
    for test in tests:
        trace(test.ljust(max(map(len, tests)) + 1))
        match test:
            case 'In':
                trace(3 in X)                          # Membership
            case 'For':
                for i in X:                            # for-loop iteration
                    trace(i, end='| ')
            case 'Comp':
                trace([i ** 2 for i in X])             # Other Iteration tools
            case 'Map':
                trace(list(map(bin, X)))
            case 'Manual':
                I = iter(X)                            # Manual iteration
                while True:
                    try:
                        trace(next(I), end='| ')
                    except StopIteration:
                        break
        print()

if __name__ == '__main__': self_test(Iters)            # Test Iters here



[Home page] Books Code Blog Python Author Train Find ©M.Lutz