cs61a spring 2018 Lab 6: Object-Oriented Programming 1

笔记摘录

Nonloacl

A variable is nonlocal to a frame if it is defined in the environment that the frame belongs to but not the frame itself, i.e. in its parent or ancestor frame.
for example:

def make_adder(x):
    """ Returns a one-argument function that returns the result of
    adding x and its argument. """
    def adder(y):
        return x + y
    return adder

when we call make_adder, we create a function adder that is able to look up the name x in make_adder’s frame and use its value.

the different between the below function:

def make_counter():
    """Makes a counter function.

    >>> counter = make_counter()
    >>> counter()
    1
    >>> counter()
    2
    """
    count = 0
    def counter():
        count = count + 1
        return count
    return counter

There will be a UnboundLocalError. Because you try to compute count + 1 before the local variable was created! count is a local variable belongs to counter’s frame.

the nonlocal keyword. It allows us to update a variable in a parent frame!

 def make_counter():
    """Makes a counter function.

    >>> counter = make_counter()
    >>> counter()
    1
    >>> counter()
    2
    """
    count = 0
    def counter():
        nonlocal count
        count = count + 1
        return count
    return counter

The line nonlocal count tells Python that count will not be local to this frame, so it will look for it in parent frames. Now we can update count without running into problems.

Object-Oriented Programming

For a car class:

constructor

The constructor of a class is a function that creates an instance, or one single occurrence, of the object outlined by the class. Like this

def __init__(self, make, model):
    self.make = make
    self.model = model
    self.color = 'No color yet. You need to paint me.'
    self.wheels = Car.num_wheels
    self.gas = Car.gas

make an instance of a class by using the name of the class.

>>> hilfingers_car = Car('Tesla', 'Model S')

attributes

class Car(object):
    num_wheels = 4
    gas = 30
    headlights = 2
    size = 'Tiny'

    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.color = 'No color yet. You need to paint me.'
        self.wheels = Car.num_wheels
        self.gas = Car.gas

    def paint(self, color):
        self.color = color
        return self.make + ' ' + self.model + ' is now ' + color

An instance attribute is a quality that is specific to an instance, and thus can only be accessed using dot notation (separating the instance and attribute with a period) on an instance. the make and model are two examples of instance attribute.
A class attribute is a quality that is shared among all instances of the class. For example, num_wheels, gas, headlights, size.

Think: Why the instance attribute gas is initialized to the value of Car.gas, the class attribute?

self.gas = Car.gas

Methods

Methods are functions that are specific to a class; only an instance of the class can use them.
dot notation to call methods on an instance

>>> hilfingers_car.paint('black')
'Tesla Model S is now black'
>>> hilfingers_car.color
'black'

You can also call methods using the class name and dot notation; for example,

>>> Car.paint(hilfingers_car, 'red')
'Tesla Model S is now red'

Think: The different between these two methods.

Inheritance

class MonsterTruck(Car):
    size = 'Monster'

    def rev(self):
        print('Vroom! This Monster Truck is huge!')

    def drive(self):
        self.rev()
        return Car.drive(self)

the class MonsterTruck is a subclass of the Car class. That means the MonsterTruck class inherits all the attributes and methods that were defined in Car, including its constructor!
add (or override) new attributes or methods that you want to be unique from those in the superclass. for example, the size.

>>> hilfingers_car.size
'Tiny'
>>> hilfingers_truck.size
'Monster'

Questions

Q1

class Car(object):
    num_wheels = 4
    gas = 30
    headlights = 2
    size = 'Tiny'

    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.color = 'No color yet. You need to paint me.'
        self.wheels = Car.num_wheels
        self.gas = Car.gas

    def paint(self, color):
        self.color = color
        return self.make + ' ' + self.model + ' is now ' + color

    def drive(self):
        if self.wheels < Car.num_wheels or self.gas <= 0:
            return self.make + ' ' + self.model + ' cannot drive!'
        self.gas -= 10
        return self.make + ' ' + self.model + ' goes vroom!'

    def pop_tire(self):
        if self.wheels > 0:
            self.wheels -= 1

    def fill_gas(self):
        self.gas += 20
        return self.make + ' ' + self.model + ' gas level: ' + str(self.gas)

class MonsterTruck(Car):
    size = 'Monster'

    def rev(self):
        print('Vroom! This Monster Truck is huge!')

    def drive(self):
        self.rev()
        return Car.drive(self)

https://goo.gl/KnGDEH

class Car(object):
    num_wheels = 4
    gas = 30
    headlights = 2
    size = 'Tiny'

    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.color = 'No color yet. You need to paint me.'
        self.wheels = Car.num_wheels
        self.gas = Car.gas

    def paint(self, color):
        self.color = color
        return self.make + ' ' + self.model + ' is now ' + color

    def drive(self):
        if self.wheels < Car.num_wheels or self.gas <= 0:
            return self.make + ' ' + self.model + ' cannot drive!'
        self.gas -= 10
        return self.make + ' ' + self.model + ' goes vroom!'

    def pop_tire(self):
        if self.wheels > 0:
            self.wheels -= 1

    def fill_gas(self):
        self.gas += 20
        return self.make + ' ' + self.model + ' gas level: ' + str(self.gas)

class MonsterTruck(Car):
    size = 'Monster'

    def rev(self):
        print('Vroom! This Monster Truck is huge!')

    def drive(self):
        self.rev()
        return Car.drive(self)


hilfingers_car = Car('Tesla', 'Model S')
print(hilfingers_car.color)
print(hilfingers_car.paint('black'))
print( hilfingers_car.color)
hilfingers_truck = MonsterTruck('Monster Truck', 'XXL')
print(hilfingers_car.size)
print(hilfingers_truck.size)

print(hilfingers_car.drive())
print(hilfingers_car.drive())
print(hilfingers_car.gas)
print(Car.gas)

print(Car.headlights)
print(hilfingers_car.headlights)
Car.headlights = 3
print(hilfingers_car.headlights)
hilfingers_car.headlights = 2
print(Car.headlights)

hilfingers_car.wheels = 2
print(hilfingers_car.wheels)
print(Car.num_wheels)
print(hilfingers_car.drive())
# Car.drive() #TypeError: drive() missing 1 required positional argument: 'self'
print(Car.drive(hilfingers_car))
# print(MonsterTruck.drive(hilfingers_car)) #AttributeError: 'Car' object has no attribute 'rev'

https://goo.gl/HH2n7c

class Car(object):
    num_wheels = 4
    gas = 30
    headlights = 2
    size = 'Tiny'

    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.color = 'No color yet. You need to paint me.'
        self.wheels = Car.num_wheels
        self.gas = Car.gas

    def paint(self, color):
        self.color = color
        return self.make + ' ' + self.model + ' is now ' + color

    def drive(self):
        if self.wheels < Car.num_wheels or self.gas <= 0:
            return self.make + ' ' + self.model + ' cannot drive!'
        self.gas -= 10
        return self.make + ' ' + self.model + ' goes vroom!'

    def pop_tire(self):
        if self.wheels > 0:
            self.wheels -= 1

    def fill_gas(self):
        self.gas += 20
        return self.make + ' ' + self.model + ' gas level: ' + str(self.gas)

class MonsterTruck(Car):
    size = 'Monster'

    def rev(self):
        print('Vroom! This Monster Truck is huge!')

    def drive(self):
        self.rev()
        return Car.drive(self)


hilfingers_car = Car('Tesla', 'Model S')
deneros_car = MonsterTruck('Monster', 'Batmobile')
auto = deneros_car.drive()
print(auto)
print(Car.drive(deneros_car))

MonsterTruck.drive(deneros_car)
Car.rev(deneros_car) # AttributeError: type object 'Car' has no attribute 'rev'

p2

class Car(object):
    num_wheels = 4
    gas = 30
    headlights = 2
    size = 'Tiny'

    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.color = 'No color yet. You need to paint me.'
        self.wheels = Car.num_wheels
        self.gas = Car.gas

    def paint(self, color):
        self.color = color
        return self.make + ' ' + self.model + ' is now ' + color

    def drive(self):
        if self.wheels < Car.num_wheels or self.gas <= 0:
            return self.make + ' ' + self.model + ' cannot drive!'
        self.gas -= 10
        return self.make + ' ' + self.model + ' goes vroom!'

    def pop_tire(self):
        if self.wheels > 0:
            self.wheels -= 1

    def fill_gas(self):
        self.gas += 20
        return self.make + ' ' + self.model + ' gas level: ' + str(self.gas)

class MonsterTruck(Car):
    size = 'Monster'

    def rev(self):
        print('Vroom! This Monster Truck is huge!')

    def drive(self):
        self.rev()
        return Car.drive(self)

class FoodTruck(MonsterTruck):
    delicious = 'meh'
    def serve(self):
        if FoodTruck.size == 'delicious':
            print('Yum!')
        if self.food != 'Tacos':
            return 'But no tacos...'
        else:
            return 'Mmm!'

taco_truck = FoodTruck('Tacos', 'Truck')
taco_truck.food = 'Guacamole'
print(taco_truck.serve())
taco_truck.size = 'delicious'
print(taco_truck.serve())
# FoodTruck.pop_tire() # TypeError: pop_tire() missing 1 required positional argument: 'self'

FoodTruck.pop_tire(taco_truck)
taco_truck.drive()

https://goo.gl/XEP2b4
p3


原文地址: https://inst.eecs.berkeley.edu/~cs61a/sp18/lab/lab06/

posted @ 2018-06-14 10:36  Siucaan  阅读(1226)  评论(0编辑  收藏  举报