1
play

1 Attributes, Functions, and Methods Looking Up Attributes by Name - PDF document

Announcements HW7 due on Wednesday Ants project out CS61A Lecture 20 Amir Kamil and Julia Oh UC Berkeley March 8, 2013 Dot Expressions Accessing Attributes Using getattr , we can look up an attribute using a string, just Objects receive


  1. Announcements  HW7 due on Wednesday  Ants project out CS61A Lecture 20 Amir Kamil and Julia Oh UC Berkeley March 8, 2013 Dot Expressions Accessing Attributes Using getattr , we can look up an attribute using a string, just Objects receive messages via dot notation as we did with a dispatch function/dictionary Dot notation accesses attributes of the instance or its class >>> getattr(tom_account, 'balance') <expression> . <name> 10 The <expression> can be any valid Python expression >>> hasattr(tom_account, 'deposit') True The <name> must be a simple name getattr and dot expressions look up a name in the same way Evaluates to the value of the attribute looked up by <name> in the object that is the value of the <expression> Looking up an attribute name in an object may return: • One of its instance attributes, or tom_account.deposit(10) Call expression Dot expression • One of the attributes of its class Methods and Functions Methods and Currying Earlier, we saw currying , which converts a function that takes in Python distinguishes between: multiple arguments into multiple chained functions. • Functions , which we have been creating since the beginning of the course, and The same procedure can be used to create a bound method • Bound methods , which couple together a function and the from a function object on which that method will be invoked. def curry(f): def outer(x): Object + Function = Bound Method def inner(*args): return f(x, *args) >>> type(Account.deposit) return inner <class 'function'> >>> add2 = curry(add)(2) return outer >>> type(tom_account.deposit) >>> add2(3) <class 'method'> 5 >>> Account.deposit(tom_account, 1001) >>> tom_deposit = curry(Account.deposit)(tom_account) 1011 >>> tom_deposit(1000) >>> tom_account.deposit(1000) 3011 2011 1

  2. Attributes, Functions, and Methods Looking Up Attributes by Name All objects have attributes, which are name ‐ value pairs <expression> . <name> Classes are objects too, so they have attributes To evaluate a dot expression: Instance attributes: attributes of instance objects Class attributes: attributes of class objects 1. Evaluate the <expression>. Terminology: Python object system: 2. <name> is matched against the instance attributes. Functions are objects. 3. If not found, <name> is looked up in the class. Bound methods are also objects: a Class function that has its first parameter 4. That class attribute value is returned unless it is a Functions Attributes Methods "self" already bound to an instance. function , in which case a bound method is returned. Dot expressions on instances evaluate to bound methods for class attributes that are functions. Class Attributes Assignment to Attributes Assignment statements with a dot expression on their left ‐ hand Class attributes are "shared" across all instances of a class side affect attributes for the object of that dot expression because they are attributes of the class, not the instance. • If the object is an instance, then assignment sets an instance class Account(object): attribute interest = 0.02 # Class attribute • If the object is a class, then assignment sets a class attribute def __init__(self, account_holder): self.balance = 0 # Instance attribute Instance tom_account.interest = 0.08 Attribute self.holder = account_holder Attribute : assignment Assignment # Additional methods would be defined here This expression evaluates to statement adds an object or modifies the >>> tom_account = Account('Tom') “interest” >>> jim_account = Account('Jim') attribute of But the name (“interest”) is not >>> tom_account.interest interest is not part of the tom_account looked up 0.02 instance that was somehow >>> jim_account.interest Class Attribute Assignment : copied from the class! Account.interest = 0.04 0.02 Attribute Assignment Statements Inheritance A technique for relating classes together Account class interest: 0.02 0.04 0.05 (withdraw, deposit, __init__) attributes Common use: Similar classes differ in amount of specialization Two classes have overlapping attribute sets, but one represents balance: 0 balance: 0 a special case of the other. holder: 'Jim' holder: 'Tom' interest: 0.08 class <name>(<base class>): >>> jim_account = Account('Jim') >>> jim_account.interest = 0.08 <suite> >>> tom_account = Account('Tom') >>> jim_account.interest >>> tom_account.interest 0.08 Conceptually, the new subclass "shares" attributes with its 0.02 >>> tom_account.interest base class. >>> jim_account.interest 0.04 0.02 >>> Account.interest = 0.05 The subclass may override certain inherited attributes. >>> tom_account.interest >>> tom_account.interest 0.02 0.05 Using inheritance, we implement a subclass by specifying its >>> Account.interest = 0.04 >>> jim_account.interest difference from the base class. >>> tom_account.interest 0.08 0.04 2

  3. Inheritance Example Looking Up Attribute Names on Classes A CheckingAccount is a specialized type of Account . Base class attributes aren't copied into subclasses! >>> ch = CheckingAccount('Tom') To look up a name in a class. >>> ch.interest # Lower interest rate for checking accounts 0.01 1. If it names an attribute in the class, return the attribute value. >>> ch.deposit(20) # Deposits are the same 2. Otherwise, look up the name in the base class, if there is one. 20 >>> ch.withdraw(5) # Withdrawals incur a $1 fee 14 >>> ch = CheckingAccount('Tom') # Calls Account.__init__ Most behavior is shared with the base class Account >>> ch.interest # Found in CheckingAccount 0.01 class CheckingAccount(Account): """A bank account that charges for withdrawals.""" >>> ch.deposit(20) # Found in Account withdraw_fee = 1 20 interest = 0.01 >>> ch.withdraw(5) # Found in CheckingAccount def withdraw(self, amount): return Account.withdraw(self, 14 amount + self.withdraw_fee) Designing for Inheritance General Base Classes Base classes may contain logic that is meant for subclasses. Don't repeat yourself; use existing implementations. Example: Same CheckingAccount behavior; different Attributes that have been overridden are still accessible via approach class objects. class Account(object): Look up attributes on instances whenever possible. interest = 0.02 May be overridden by subclasses withdraw_fee = 0 class CheckingAccount(Account): def withdraw(self, amount): """A bank account that charges for withdrawals.""" amount += self.withdraw_fee withdraw_fee = 1 if amount > self.balance: interest = 0.01 return 'Insufficient funds' def withdraw(self, amount): self.balance = self.balance – amount return Account.withdraw(self, return self.balance amount + self.withdraw_fee) Attribute look ‐ up class CheckingAccount(Account): Preferable alternative to on base class interest = 0.01 Nothing else needed in this class CheckingAccount.withdraw_fee withdraw_fee = 1 Inheritance and Composition Multiple Inheritance class SavingsAccount(Account): Object ‐ oriented programming shines when we adopt the deposit_fee = 2 metaphor. def deposit(self, amount): return Account.deposit(self, Inheritance is best for representing is ‐ a relationships. amount - self.deposit_fee) A class may inherit from multiple base classes in Python. E.g., a checking account is a specific type of account. CleverBank marketing executive wants: So, CheckingAccount inherits from Account . • Low interest rate of 1% Composition is best for representing has ‐ a relationships. • A $1 fee for withdrawals • A $2 fee for deposits E.g., a bank has a collection of bank accounts it manages. • A free dollar when you open your account So, A bank has a list of Account instances as an attribute. class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): No local state at all? Just write a pure function! self.holder = account_holder self.balance = 1 # A free dollar! 3

  4. Multiple Inheritance Resolving Ambiguous Class Attribute Names A class may inherit from multiple base classes in Python. Account class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): CheckingAccount SavingsAccount def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar! AsSeenOnTVAccount >>> such_a_deal = AsSeenOnTVAccount("John") >>> such_a_deal = AsSeenOnTVAccount("John") Instance attribute Instance attribute >>> such_a_deal.balance >>> such_a_deal.balance 1 1 SavingsAccount SavingsAccount >>> such_a_deal.deposit(20) >>> such_a_deal.deposit(20) method method 19 19 >>> such_a_deal.withdraw(5) >>> such_a_deal.withdraw(5) CheckingAccount CheckingAccount 13 13 method method Human Relationships Some_Guy Grandma Grandpa Grandaddy Gramammy Double Half Aunt Mom Dad Double Half Uncle Some_Dude You Quadruple Double Half Cousin 4

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend