Inheritance Announcements Attributes Methods and Functions 4 - - PowerPoint PPT Presentation

inheritance announcements attributes methods and functions
SMART_READER_LITE
LIVE PREVIEW

Inheritance Announcements Attributes Methods and Functions 4 - - PowerPoint PPT Presentation

Inheritance Announcements Attributes Methods and Functions 4 Methods and Functions Python distinguishes between: 4 Methods and Functions Python distinguishes between: Functions , which we have been creating since the beginning of the


slide-1
SLIDE 1

Inheritance

slide-2
SLIDE 2

Announcements

slide-3
SLIDE 3

Attributes

slide-4
SLIDE 4

Methods and Functions

4

slide-5
SLIDE 5

Methods and Functions

Python distinguishes between:

4

slide-6
SLIDE 6

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and

4

slide-7
SLIDE 7

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked

4

slide-8
SLIDE 8

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method

4

slide-9
SLIDE 9

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit)

4

slide-10
SLIDE 10

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit) <class 'function'>

4

slide-11
SLIDE 11

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit) <class 'function'> >>> type(tom_account.deposit)

4

slide-12
SLIDE 12

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit) <class 'function'> >>> type(tom_account.deposit) <class 'method'>

4

slide-13
SLIDE 13

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit) <class 'function'> >>> type(tom_account.deposit) <class 'method'> >>> Account.deposit(tom_account, 1001) 1011

4

slide-14
SLIDE 14

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit) <class 'function'> >>> type(tom_account.deposit) <class 'method'> >>> Account.deposit(tom_account, 1001) 1011 >>> tom_account.deposit(1004) 2015

4

slide-15
SLIDE 15

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit) <class 'function'> >>> type(tom_account.deposit) <class 'method'> >>> Account.deposit(tom_account, 1001) 1011 >>> tom_account.deposit(1004) 2015

4

Function: all arguments within parentheses

slide-16
SLIDE 16

Methods and Functions

Python distinguishes between:

  • Functions, which we have been creating since the beginning of the course, and
  • Bound methods, which couple together a function and the object on which that

method will be invoked Object + Function = Bound Method >>> type(Account.deposit) <class 'function'> >>> type(tom_account.deposit) <class 'method'> >>> Account.deposit(tom_account, 1001) 1011 >>> tom_account.deposit(1004) 2015

4

Function: all arguments within parentheses Method: One object before the dot and

  • ther arguments within parentheses
slide-17
SLIDE 17

Terminology: Attributes, Functions, and Methods

5

slide-18
SLIDE 18

Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs

5

slide-19
SLIDE 19

Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes

5

slide-20
SLIDE 20

Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance

5

slide-21
SLIDE 21

Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance

5

slide-22
SLIDE 22

Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance Terminology:

5

slide-23
SLIDE 23

Class
 Attributes


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance Terminology:

5

slide-24
SLIDE 24

Class
 Attributes
 Functions


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance Terminology:

5

slide-25
SLIDE 25

Class
 Attributes
 Functions


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance

Methods

Terminology:

5

slide-26
SLIDE 26

Class
 Attributes
 Functions


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance

Methods

Terminology: Python object system:

5

slide-27
SLIDE 27

Class
 Attributes
 Functions


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance

Methods

Functions are objects Terminology: Python object system:

5

slide-28
SLIDE 28

Class
 Attributes
 Functions


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance

Methods

Functions are objects Bound methods are also objects: a function that has its first parameter "self" already bound to an instance Terminology: Python object system:

5

slide-29
SLIDE 29

Class
 Attributes
 Functions


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance

Methods

Functions are objects Bound methods are also objects: a function that has its first parameter "self" already bound to an instance Dot expressions evaluate to bound methods for class attributes that are functions Terminology: Python object system:

5

slide-30
SLIDE 30

Class
 Attributes
 Functions


Terminology: Attributes, Functions, and Methods

All objects have attributes, which are name-value pairs Classes are objects too, so they have attributes Instance attribute: attribute of an instance Class attribute: attribute of the class of an instance

Methods

Functions are objects Bound methods are also objects: a function that has its first parameter "self" already bound to an instance Dot expressions evaluate to bound methods for class attributes that are functions Terminology: Python object system:

5

<instance>.<method_name>

slide-31
SLIDE 31

Looking Up Attributes by Name

<expression> . <name>

6

slide-32
SLIDE 32

Looking Up Attributes by Name

<expression> . <name> To evaluate a dot expression:

6

slide-33
SLIDE 33

Looking Up Attributes by Name

<expression> . <name> To evaluate a dot expression: 1. Evaluate the <expression> to the left of the dot, which yields the object of the dot expression

6

slide-34
SLIDE 34

Looking Up Attributes by Name

<expression> . <name> To evaluate a dot expression: 1. Evaluate the <expression> to the left of the dot, which yields the object of the dot expression 2. <name> is matched against the instance attributes of that object; if an attribute with that name exists, its value is returned

6

slide-35
SLIDE 35

Looking Up Attributes by Name

<expression> . <name> To evaluate a dot expression: 1. Evaluate the <expression> to the left of the dot, which yields the object of the dot expression 2. <name> is matched against the instance attributes of that object; if an attribute with that name exists, its value is returned 3. If not, <name> is looked up in the class, which yields a class attribute value

6

slide-36
SLIDE 36

Looking Up Attributes by Name

<expression> . <name> To evaluate a dot expression: 1. Evaluate the <expression> to the left of the dot, which yields the object of the dot expression 2. <name> is matched against the instance attributes of that object; if an attribute with that name exists, its value is returned 3. If not, <name> is looked up in the class, which yields a class attribute value 4. That value is returned unless it is a function, in which case a bound method is returned instead

6

slide-37
SLIDE 37

Class Attributes

7

slide-38
SLIDE 38

Class Attributes

Class attributes are "shared" across all instances of a class because they are attributes

  • f the class, not the instance

7

slide-39
SLIDE 39

Class Attributes

Class attributes are "shared" across all instances of a class because they are attributes

  • f the class, not the instance

class Account: interest = 0.02 # A class attribute def __init__(self, account_holder): self.balance = 0 self.holder = account_holder # Additional methods would be defined here

7

slide-40
SLIDE 40

Class Attributes

Class attributes are "shared" across all instances of a class because they are attributes

  • f the class, not the instance

class Account: interest = 0.02 # A class attribute def __init__(self, account_holder): self.balance = 0 self.holder = account_holder # Additional methods would be defined here

7

>>> tom_account = Account('Tom')

slide-41
SLIDE 41

Class Attributes

Class attributes are "shared" across all instances of a class because they are attributes

  • f the class, not the instance

class Account: interest = 0.02 # A class attribute def __init__(self, account_holder): self.balance = 0 self.holder = account_holder # Additional methods would be defined here

7

>>> tom_account = Account('Tom') >>> jim_account = Account('Jim')

slide-42
SLIDE 42

Class Attributes

Class attributes are "shared" across all instances of a class because they are attributes

  • f the class, not the instance

class Account: interest = 0.02 # A class attribute def __init__(self, account_holder): self.balance = 0 self.holder = account_holder # Additional methods would be defined here

7

>>> tom_account = Account('Tom') >>> jim_account = Account('Jim') >>> tom_account.interest 0.02

slide-43
SLIDE 43

Class Attributes

Class attributes are "shared" across all instances of a class because they are attributes

  • f the class, not the instance

class Account: interest = 0.02 # A class attribute def __init__(self, account_holder): self.balance = 0 self.holder = account_holder # Additional methods would be defined here The interest attribute is not part of the instance; it's part of the class!

7

>>> tom_account = Account('Tom') >>> jim_account = Account('Jim') >>> tom_account.interest 0.02

slide-44
SLIDE 44

Class Attributes

Class attributes are "shared" across all instances of a class because they are attributes

  • f the class, not the instance

class Account: interest = 0.02 # A class attribute def __init__(self, account_holder): self.balance = 0 self.holder = account_holder # Additional methods would be defined here The interest attribute is not part of the instance; it's part of the class!

7

>>> tom_account = Account('Tom') >>> jim_account = Account('Jim') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02

slide-45
SLIDE 45

Attribute Assignment

slide-46
SLIDE 46

Assignment to Attributes

9

slide-47
SLIDE 47

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

9

slide-48
SLIDE 48

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute

9

slide-49
SLIDE 49

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

9

slide-50
SLIDE 50

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

9

class Account: interest = 0.02 def __init__(self, holder): self.holder = holder self.balance = 0 ... tom_account = Account('Tom')

slide-51
SLIDE 51

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

tom_account.interest = 0.08

9

class Account: interest = 0.02 def __init__(self, holder): self.holder = holder self.balance = 0 ... tom_account = Account('Tom')

slide-52
SLIDE 52

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

tom_account.interest = 0.08 This expression evaluates to an

  • bject

9

class Account: interest = 0.02 def __init__(self, holder): self.holder = holder self.balance = 0 ... tom_account = Account('Tom')

slide-53
SLIDE 53

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

tom_account.interest = 0.08 But the name (“interest”) is not looked up This expression evaluates to an

  • bject

9

class Account: interest = 0.02 def __init__(self, holder): self.holder = holder self.balance = 0 ... tom_account = Account('Tom')

slide-54
SLIDE 54

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

tom_account.interest = 0.08 But the name (“interest”) is not looked up Attribute assignment statement adds

  • r modifies the

attribute named “interest” of tom_account This expression evaluates to an

  • bject

9

class Account: interest = 0.02 def __init__(self, holder): self.holder = holder self.balance = 0 ... tom_account = Account('Tom')

slide-55
SLIDE 55

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

tom_account.interest = 0.08 But the name (“interest”) is not looked up Attribute assignment statement adds

  • r modifies the

attribute named “interest” of tom_account Instance Attribute Assignment : This expression evaluates to an

  • bject

9

class Account: interest = 0.02 def __init__(self, holder): self.holder = holder self.balance = 0 ... tom_account = Account('Tom')

slide-56
SLIDE 56

Assignment to Attributes

Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression

  • If the object is an instance, then assignment sets an instance attribute
  • If the object is a class, then assignment sets a class attribute

tom_account.interest = 0.08 But the name (“interest”) is not looked up Attribute assignment statement adds

  • r modifies the

attribute named “interest” of tom_account Instance Attribute Assignment : Account.interest = 0.04 Class Attribute Assignment : This expression evaluates to an

  • bject

9

class Account: interest = 0.02 def __init__(self, holder): self.holder = holder self.balance = 0 ... tom_account = Account('Tom')

slide-57
SLIDE 57

Attribute Assignment Statements

interest: 0.02 (withdraw, deposit, __init__) Account class attributes

10

slide-58
SLIDE 58

Attribute Assignment Statements

>>> jim_account = Account('Jim') interest: 0.02 (withdraw, deposit, __init__) Account class attributes

10

slide-59
SLIDE 59

Attribute Assignment Statements

>>> jim_account = Account('Jim') interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' Account class attributes

10

Instance attributes of jim_account

slide-60
SLIDE 60

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' Account class attributes

10

Instance attributes of jim_account

slide-61
SLIDE 61

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes

10

Instance attributes of jim_account Instance attributes of tom_account

slide-62
SLIDE 62

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes

10

Instance attributes of jim_account Instance attributes of tom_account

slide-63
SLIDE 63

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes

10

Instance attributes of jim_account Instance attributes of tom_account

slide-64
SLIDE 64

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes

10

Instance attributes of jim_account Instance attributes of tom_account

slide-65
SLIDE 65

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04

10

Instance attributes of jim_account Instance attributes of tom_account

slide-66
SLIDE 66

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04

10

Instance attributes of jim_account Instance attributes of tom_account

slide-67
SLIDE 67

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04

10

Instance attributes of jim_account Instance attributes of tom_account

slide-68
SLIDE 68

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04

10

Instance attributes of jim_account Instance attributes of tom_account

slide-69
SLIDE 69

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04 interest: 0.08

10

Instance attributes of jim_account Instance attributes of tom_account

slide-70
SLIDE 70

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 >>> jim_account.interest 0.08 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04 interest: 0.08

10

Instance attributes of jim_account Instance attributes of tom_account

slide-71
SLIDE 71

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 >>> jim_account.interest 0.08 >>> tom_account.interest 0.04 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04 interest: 0.08

10

Instance attributes of jim_account Instance attributes of tom_account

slide-72
SLIDE 72

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 >>> jim_account.interest 0.08 >>> tom_account.interest 0.04 >>> Account.interest = 0.05 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04 interest: 0.08

10

Instance attributes of jim_account Instance attributes of tom_account

slide-73
SLIDE 73

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 >>> jim_account.interest 0.08 >>> tom_account.interest 0.04 >>> Account.interest = 0.05 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04 interest: 0.08 0.05

10

Instance attributes of jim_account Instance attributes of tom_account

slide-74
SLIDE 74

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 >>> jim_account.interest 0.08 >>> tom_account.interest 0.04 >>> Account.interest = 0.05 >>> tom_account.interest 0.05 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04 interest: 0.08 0.05

10

Instance attributes of jim_account Instance attributes of tom_account

slide-75
SLIDE 75

Attribute Assignment Statements

>>> jim_account = Account('Jim') >>> tom_account = Account('Tom') >>> tom_account.interest 0.02 >>> jim_account.interest 0.02 >>> Account.interest = 0.04 >>> tom_account.interest 0.04 >>> jim_account.interest 0.04 >>> jim_account.interest = 0.08 >>> jim_account.interest 0.08 >>> tom_account.interest 0.04 >>> Account.interest = 0.05 >>> tom_account.interest 0.05 >>> jim_account.interest 0.08 interest: 0.02 (withdraw, deposit, __init__) balance: 0 holder: 'Jim' balance: 0 holder: 'Tom' Account class attributes 0.04 interest: 0.08 0.05

10

Instance attributes of jim_account Instance attributes of tom_account

slide-76
SLIDE 76

Inheritance

slide-77
SLIDE 77

Inheritance

12

slide-78
SLIDE 78

Inheritance

Inheritance is a technique for relating classes together

12

slide-79
SLIDE 79

Inheritance

Inheritance is a technique for relating classes together A common use: Two similar classes differ in their degree of specialization

12

slide-80
SLIDE 80

Inheritance

Inheritance is a technique for relating classes together A common use: Two similar classes differ in their degree of specialization The specialized class may have the same attributes as the general class, along with some special-case behavior

12

slide-81
SLIDE 81

Inheritance

Inheritance is a technique for relating classes together A common use: Two similar classes differ in their degree of specialization The specialized class may have the same attributes as the general class, along with some special-case behavior

12

class <Name>(<Base Class>): <suite>

slide-82
SLIDE 82

Inheritance

Inheritance is a technique for relating classes together A common use: Two similar classes differ in their degree of specialization The specialized class may have the same attributes as the general class, along with some special-case behavior

12

class <Name>(<Base Class>): <suite> Conceptually, the new subclass inherits attributes of its base class

slide-83
SLIDE 83

Inheritance

Inheritance is a technique for relating classes together A common use: Two similar classes differ in their degree of specialization The specialized class may have the same attributes as the general class, along with some special-case behavior

12

class <Name>(<Base Class>): <suite> Conceptually, the new subclass inherits attributes of its base class The subclass may override certain inherited attributes

slide-84
SLIDE 84

Inheritance

Inheritance is a technique for relating classes together A common use: Two similar classes differ in their degree of specialization The specialized class may have the same attributes as the general class, along with some special-case behavior

12

class <Name>(<Base Class>): <suite> Conceptually, the new subclass inherits attributes of its base class The subclass may override certain inherited attributes Using inheritance, we implement a subclass by specifying its differences from the the base class

slide-85
SLIDE 85

Inheritance Example

A CheckingAccount is a specialized type of Account

13

slide-86
SLIDE 86

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom')

13

slide-87
SLIDE 87

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01

13

slide-88
SLIDE 88

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20

13

slide-89
SLIDE 89

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14

13

slide-90
SLIDE 90

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account

13

slide-91
SLIDE 91

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account):

13

slide-92
SLIDE 92

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals."""

13

slide-93
SLIDE 93

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1

13

slide-94
SLIDE 94

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01

13

slide-95
SLIDE 95

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount):

13

slide-96
SLIDE 96

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

13

slide-97
SLIDE 97

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

13

slide-98
SLIDE 98
  • r

return super().withdraw( amount + self.withdraw_fee)

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

13

slide-99
SLIDE 99
  • r

return super().withdraw( amount + self.withdraw_fee)

Inheritance Example

A CheckingAccount is a specialized type of Account >>> ch = CheckingAccount('Tom') >>> ch.interest # Lower interest rate for checking accounts 0.01 >>> ch.deposit(20) # Deposits are the same 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 Most behavior is shared with the base class Account class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

13

slide-100
SLIDE 100

Looking Up Attribute Names on Classes

Base class attributes aren't copied into subclasses!

14

slide-101
SLIDE 101

Looking Up Attribute Names on Classes

To look up a name in a class: Base class attributes aren't copied into subclasses!

14

slide-102
SLIDE 102

Looking Up Attribute Names on Classes

To look up a name in a class:

  • 1. If it names an attribute in the class, return the attribute value.

Base class attributes aren't copied into subclasses!

14

slide-103
SLIDE 103

Looking Up Attribute Names on Classes

To look up a name in a class:

  • 1. If it names an attribute in the class, return the attribute value.
  • 2. Otherwise, look up the name in the base class, if there is one.

Base class attributes aren't copied into subclasses!

14

slide-104
SLIDE 104

Looking Up Attribute Names on Classes

To look up a name in a class:

  • 1. If it names an attribute in the class, return the attribute value.
  • 2. Otherwise, look up the name in the base class, if there is one.

>>> ch = CheckingAccount('Tom') # Calls Account.__init__ Base class attributes aren't copied into subclasses!

14

slide-105
SLIDE 105

Looking Up Attribute Names on Classes

To look up a name in a class:

  • 1. If it names an attribute in the class, return the attribute value.
  • 2. Otherwise, look up the name in the base class, if there is one.

>>> ch = CheckingAccount('Tom') # Calls Account.__init__ >>> ch.interest # Found in CheckingAccount 0.01 Base class attributes aren't copied into subclasses!

14

slide-106
SLIDE 106

Looking Up Attribute Names on Classes

To look up a name in a class:

  • 1. If it names an attribute in the class, return the attribute value.
  • 2. Otherwise, look up the name in the base class, if there is one.

>>> ch = CheckingAccount('Tom') # Calls Account.__init__ >>> ch.interest # Found in CheckingAccount 0.01 >>> ch.deposit(20) # Found in Account 20 Base class attributes aren't copied into subclasses!

14

slide-107
SLIDE 107

Looking Up Attribute Names on Classes

To look up a name in a class:

  • 1. If it names an attribute in the class, return the attribute value.
  • 2. Otherwise, look up the name in the base class, if there is one.

>>> ch = CheckingAccount('Tom') # Calls Account.__init__ >>> ch.interest # Found in CheckingAccount 0.01 >>> ch.deposit(20) # Found in Account 20 >>> ch.withdraw(5) # Found in CheckingAccount 14 Base class attributes aren't copied into subclasses!

14

slide-108
SLIDE 108

Looking Up Attribute Names on Classes

To look up a name in a class:

  • 1. If it names an attribute in the class, return the attribute value.
  • 2. Otherwise, look up the name in the base class, if there is one.

>>> ch = CheckingAccount('Tom') # Calls Account.__init__ >>> ch.interest # Found in CheckingAccount 0.01 >>> ch.deposit(20) # Found in Account 20 >>> ch.withdraw(5) # Found in CheckingAccount 14 Base class attributes aren't copied into subclasses!

14

(Demo)

slide-109
SLIDE 109

Object-Oriented Design

slide-110
SLIDE 110

Designing for Inheritance

16

slide-111
SLIDE 111

Designing for Inheritance

Don't repeat yourself; use existing implementations

16

slide-112
SLIDE 112

Designing for Inheritance

Don't repeat yourself; use existing implementations

16

class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

slide-113
SLIDE 113

Designing for Inheritance

Don't repeat yourself; use existing implementations Attributes that have been overridden are still accessible via class objects

16

class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

slide-114
SLIDE 114

Designing for Inheritance

Don't repeat yourself; use existing implementations Attributes that have been overridden are still accessible via class objects Attribute look-up

  • n base class

16

class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

slide-115
SLIDE 115

Designing for Inheritance

Don't repeat yourself; use existing implementations Attributes that have been overridden are still accessible via class objects Look up attributes on instances whenever possible Attribute look-up

  • n base class

16

class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

slide-116
SLIDE 116

Designing for Inheritance

Don't repeat yourself; use existing implementations Attributes that have been overridden are still accessible via class objects Look up attributes on instances whenever possible Attribute look-up

  • n base class

Preferred to CheckingAccount.withdraw_fee to allow for specialized accounts

16

class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)

slide-117
SLIDE 117

Inheritance and Composition

17

slide-118
SLIDE 118

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor

17

slide-119
SLIDE 119

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor Inheritance is best for representing is-a relationships

17

slide-120
SLIDE 120

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor Inheritance is best for representing is-a relationships

  • E.g., a checking account is a specific type of account

17

slide-121
SLIDE 121

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor Inheritance is best for representing is-a relationships

  • E.g., a checking account is a specific type of account
  • So, CheckingAccount inherits from Account

17

slide-122
SLIDE 122

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor Inheritance is best for representing is-a relationships

  • E.g., a checking account is a specific type of account
  • So, CheckingAccount inherits from Account

Composition is best for representing has-a relationships

17

slide-123
SLIDE 123

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor Inheritance is best for representing is-a relationships

  • E.g., a checking account is a specific type of account
  • So, CheckingAccount inherits from Account

Composition is best for representing has-a relationships

  • E.g., a bank has a collection of bank accounts it manages

17

slide-124
SLIDE 124

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor Inheritance is best for representing is-a relationships

  • E.g., a checking account is a specific type of account
  • So, CheckingAccount inherits from Account

Composition is best for representing has-a relationships

  • E.g., a bank has a collection of bank accounts it manages
  • So, A bank has a list of accounts as an attribute

17

slide-125
SLIDE 125

Inheritance and Composition

Object-oriented programming shines when we adopt the metaphor Inheritance is best for representing is-a relationships

  • E.g., a checking account is a specific type of account
  • So, CheckingAccount inherits from Account

Composition is best for representing has-a relationships

  • E.g., a bank has a collection of bank accounts it manages
  • So, A bank has a list of accounts as an attribute

17

(Demo)

slide-126
SLIDE 126

Attributes Lookup Practice

slide-127
SLIDE 127

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z

slide-128
SLIDE 128

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z z: -1 f: <class A> func f(self, x)

slide-129
SLIDE 129

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z z: -1 f: <class A> func f(self, x) Global

slide-130
SLIDE 130

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z z: -1 f: <class A> func f(self, x) Global A

slide-131
SLIDE 131

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) Global A

slide-132
SLIDE 132

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) Global A B

slide-133
SLIDE 133

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) Global A B

slide-134
SLIDE 134

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) Global A B C

slide-135
SLIDE 135

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) Global A B C

slide-136
SLIDE 136

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) Global A B C a

slide-137
SLIDE 137

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: ... Global A B C a

slide-138
SLIDE 138

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: ... Global A B C a b

slide-139
SLIDE 139

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: ... n: 5 Global A B C a b

slide-140
SLIDE 140

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C instance> z: 2 ... n: 5 Global A B C a b

slide-141
SLIDE 141

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C instance> z: 2 ... n: 5 4 Global A B C a b

slide-142
SLIDE 142

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C instance> z: 2 ... n: 5 4 True Global A B C a b

slide-143
SLIDE 143

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C instance> z: 2 n: 5 4 True Global A B C a b

slide-144
SLIDE 144

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <B inst> z: <C instance> z: 2 n: 5 4 True Global A B C a b

slide-145
SLIDE 145

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C inst> z: <B inst> z: <C instance> z: 2 n: 5 4 True Global A B C a b

slide-146
SLIDE 146

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C inst> z: <B inst> z: <C instance> z: 2 n: 5 4 True Global A B C a b 1

slide-147
SLIDE 147

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C inst> z: <B inst> z: <C instance> z: 2 n: 5 4 True False Global A B C a b 1

slide-148
SLIDE 148

Inheritance and Attribute Lookup

class A: z = -1 def f(self, x): return B(x-1) class B(A): n = 4 def __init__(self, y): if y: self.z = self.f(y) else: self.z = C(y+1) class C(B): def f(self, x): return x a = A() b = B(1) b.n = 5

19

>>> a.z == C.z >>> C(2).n Which evaluates 
 to an integer? b.z b.z.z b.z.z.z b.z.z.z.z None of these >>> a.z == b.z <A instance> z: -1 f: <class A> func f(self, x) n: 4 __init__: <class B inherits from A> func __init__(self, y) f: <class C inherits from B> func f(self, x) <B instance> z: <C inst> z: <B inst> z: <C instance> z: 2 n: 5 4 True False Global A B C a b 1

slide-149
SLIDE 149

Multiple Inheritance

slide-150
SLIDE 150

Multiple Inheritance

21

slide-151
SLIDE 151

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee)

21

slide-152
SLIDE 152

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) A class may inherit from multiple base classes in Python

21

slide-153
SLIDE 153

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) A class may inherit from multiple base classes in Python CleverBank marketing executive has an idea:

21

slide-154
SLIDE 154

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) A class may inherit from multiple base classes in Python CleverBank marketing executive has an idea:

  • Low interest rate of 1%

21

slide-155
SLIDE 155

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) A class may inherit from multiple base classes in Python CleverBank marketing executive has an idea:

  • Low interest rate of 1%
  • A $1 fee for withdrawals

21

slide-156
SLIDE 156

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) A class may inherit from multiple base classes in Python CleverBank marketing executive has an idea:

  • Low interest rate of 1%
  • A $1 fee for withdrawals
  • A $2 fee for deposits

21

slide-157
SLIDE 157

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) A class may inherit from multiple base classes in Python CleverBank marketing executive has an idea:

  • Low interest rate of 1%
  • A $1 fee for withdrawals
  • A $2 fee for deposits
  • A free dollar when you open your account

21

slide-158
SLIDE 158

Multiple Inheritance

class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee) class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! A class may inherit from multiple base classes in Python CleverBank marketing executive has an idea:

  • Low interest rate of 1%
  • A $1 fee for withdrawals
  • A $2 fee for deposits
  • A free dollar when you open your account

21

slide-159
SLIDE 159

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar!

22

slide-160
SLIDE 160

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! >>> such_a_deal = AsSeenOnTVAccount('John')

22

slide-161
SLIDE 161

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! >>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1

22

slide-162
SLIDE 162

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! >>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1 Instance attribute

22

slide-163
SLIDE 163

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! >>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1 >>> such_a_deal.deposit(20) 19 Instance attribute

22

slide-164
SLIDE 164

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! >>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1 >>> such_a_deal.deposit(20) 19 Instance attribute SavingsAccount method

22

slide-165
SLIDE 165

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! >>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1 >>> such_a_deal.deposit(20) 19 >>> such_a_deal.withdraw(5) 13 Instance attribute SavingsAccount method

22

slide-166
SLIDE 166

Multiple Inheritance

A class may inherit from multiple base classes in Python. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! >>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1 >>> such_a_deal.deposit(20) 19 >>> such_a_deal.withdraw(5) 13 Instance attribute SavingsAccount method CheckingAccount method

22

slide-167
SLIDE 167

Resolving Ambiguous Class Attribute Names

23

>>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1 >>> such_a_deal.deposit(20) 19 >>> such_a_deal.withdraw(5) 13 Instance attribute SavingsAccount method CheckingAccount method

slide-168
SLIDE 168

Resolving Ambiguous Class Attribute Names

Account CheckingAccount SavingsAccount AsSeenOnTVAccount

23

>>> such_a_deal = AsSeenOnTVAccount('John') >>> such_a_deal.balance 1 >>> such_a_deal.deposit(20) 19 >>> such_a_deal.withdraw(5) 13 Instance attribute SavingsAccount method CheckingAccount method

slide-169
SLIDE 169

Complicated Inheritance

slide-170
SLIDE 170

Biological Inheritance

25

slide-171
SLIDE 171

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy

slide-172
SLIDE 172

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Mom Dad

slide-173
SLIDE 173

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Mom Dad You

slide-174
SLIDE 174

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Mom Dad You

slide-175
SLIDE 175

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Mom Dad You Half some_guy

slide-176
SLIDE 176

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Mom Dad You Half some_guy Half Cousin some_other_guy

slide-177
SLIDE 177

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Mom Dad You Half Half Cousin some_other_guy

slide-178
SLIDE 178

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Double Mom Dad You Half Half Cousin some_other_guy

slide-179
SLIDE 179

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Double Mom Dad You Half Half Cousin some_other_guy Double

slide-180
SLIDE 180

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Double Mom Dad You Half Double Half Uncle Half Cousin some_other_guy Double

slide-181
SLIDE 181

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Double Mom Dad You Half Double Half Uncle Half Cousin Double

slide-182
SLIDE 182

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Double Quadruple Mom Dad You Half Double Half Uncle Half Cousin

slide-183
SLIDE 183

Biological Inheritance

25

Grandma Grandpa Gramammy Grandaddy Aunt Double Quadruple Mom Dad You Half Double Half Uncle Half Cousin

Moral of the story: Inheritance can be complicated, so don't overuse it!