# Multiple inheritance class Account(object): """A bank account that allows deposits and withdrawals.""" interest = 0.02 def __init__(self, account_holder): self.balance = 0 self.holder = account_holder def deposit(self, amount): """Increase the account balance by amount and return the new balance.""" self.balance = self.balance + amount return self.balance def withdraw(self, amount): """Decrease the account balance by amount and return the new balance.""" if amount > self.balance: return 'Insufficient funds' self.balance = self.balance - amount return self.balance class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): fee = self.withdraw_fee return Account.withdraw(self, amount+fee) class SavingsAccount(Account): """A bank account that charges for deposits.""" deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): """A bank account that charges for everything.""" def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! # Method resolution order supers = [c.__name__ for c in AsSeenOnTVAccount.mro()] # Error messages from operator import add def curry(f): def outer(x): def inner(*args): return f(x, *args) return inner return outer add3 = curry(add)(3) # add3(4, 5) tom_account = Account('Tom') # tom_account.deposit(100, 200) # Inheritance and polymorphism def welfare(account): """Deposit \$100 into an account if it has less than \$100.""" if account.balance < 100: return account.deposit(100) alice_account = CheckingAccount('Alice') welfare(alice_account) bob_account = SavingsAccount('Bob') welfare(bob_account) # String representations import datetime today = datetime.date(2012, 10, 8) repr(today) str(today) # Special methods and properties from fractions import gcd class Rational(object): """A mutable fraction. >>> f = Rational(3, 5) >>> f Rational(3, 5) >>> print(f) 3/5 >>> f.float_value 0.6 >>> f.numerator = 4 >>> f.float_value 0.8 >>> f.denominator -= 3 >>> f.float_value 2.0 """ def __init__(self, numer, denom): g = gcd(numer, denom) self.numerator = numer // g self.denominator = denom // g @property def float_value(self): return self.numerator / self.denominator def __repr__(self): return 'Rational({0}, {1})'.format(self.numerator, self.denominator) def __str__(self): return '{0}/{1}'.format(self.numerator, self.denominator) def __add__(self, num): denom = self.denominator * num.denominator numer1 = self.numerator * num.denominator numer2 = self.denominator * num.numerator return Rational(numer1 + numer2, denom) def __mul__(self, num): return Rational(self.numerator * num.numerator, self.denominator * num.denominator) def __eq__(self, num): return (self.numerator == num.numerator and self.denominator == num.denominator) def __bool__(self): return self.numerator != 0