《通过艰难的方式学习Python》第二版。练习45

0 投票
4 回答
2230 浏览
提问于 2025-04-16 23:06

我正在学习《Learn Python the Hard Way》第二版,刚刚做完一个练习,要求我写出“是一个(is-a)”和“有一个(has-a)”的关系。我能用类,但对“是一个”和“有一个”这两个概念感到困惑。所以我不知道我做的是否正确,任何建议都会很感激。谢谢。

## Animal is-a object (yes, sort of confusing) look at the extra credit
class Animal(object):
    pass


## ?? Dog is-a object
class Dog(Animal):

    def __init__(self, name):
        ## ?? Dog has-a name
        self.name = name

## ?? Cat is-a object
class Cat(Animal):

    def __init__(self, name):
        ## ?? Cat has-a name
        self.name = name

class Person(object):

    def __init__(self, name):
        ## ?? Person has-a name
        self.name = name

        ## Person has-a pet of some kind
        self.pet = None

## ?? Employee is-a object
class Employee(Person):

    def __init__(self, name, salary):
        ## ?? hmm  what is this strange magic? 
        super(Employee, self).__init__(name)
        ## ?? Employee has-a salary
        self.salary = salary

## ?? Fish is-a object
class Fish(object):
    pass

## ?? Salmon is-a object, type of a fish
class Salmon(Fish):
    pass

## ?? Halibut is-a object, type of a fish
class Halibut(Fish):
    pass

## rover is-a Dog
rover = Dog("Rover")

## ?? satan is-a Cat
satan = Cat("Satan")

## ?? mary is-a person
mary = Person("Mary")

## ?? mary has-a pet called satan
mary.pet = satan

## ?? frank is-a Employee on 120000 salary
frank = Employee("Frank", 120000)

## ?? frank has-a pet called rover
frank.pet = rover

## ?? flipper is Fish
flipper = Fish()

## ?? crouse is-a Salmon
crouse = Salmon()

## ?? harry is-a Halibut
harry = Halibut()

4 个回答

1

基本上,你说的没错。你先建立一个基础类,比如说“鱼”(Fish),然后通过继承这个基础类,添加更多的细节和特性,这样就扩展了这个基础类。这就是你所说的“是一个”(is-a)关系。

比如说,员工(Employee)“是一个”人(Person),同时也“拥有一个”薪水(Salary)。薪水可以是一个单独定义的对象,一个人可能有,也可能没有。你甚至可以把这个薪水对象放到其他对象里,让它们也“拥有”这个薪水:

class AnimalActor(Dog):
   def __init__(self, salary):
      self.__salary = salary

s = Salary(50000)
lassie = AnimalActor(s)

比如“拉西”(lassie)“是一个”狗(Dog),同时也“拥有一个”薪水。

2

《艰难学Python》这本书对章节进行了调整,所以虽然以前这是第45个练习,现在变成了第42个练习。这一章讲的是“is-a”和“has-a”关系,之前我也搞不太明白。

根据我所了解的,这个问题在Stack Overflow上被认为是偏题的。不过,当我在网上寻找帮助时,这里是我找到答案的第一个地方之一,所以我就把我的答案加到这个问题里。我不太确定是否应该回答“糟糕”的问题,但我很确定我不是唯一一个在这个练习上挣扎的人;)

我的答案:

## Animal is-a object
class Animal(object):
    pass

## Dog is-a Animal (Animal is-a Object, so Dog is-a Object as well.)
class Dog(Animal):

    def __init__(self, name):
        ## Dog has-a name
        self.name = name

## Cat is-a Animal (Animal is-a Object, so Cat is-a Object as well.)
class Cat(Animal):

    def __init__(self, name):
        ## Cat has-a Name
        self.name = name

## Person is-a Object
class Person(object):

    def __init__(self, name):
        ## Person has-a name
        self.name = name

        ## Person has-a pet of some kind
        self.pet = None

## Employee is-a Person (and is-a Object, of course, everything is-a Object!)
class Employee(Person):

    def __init__(self, name, salary):
        ## ?? This is a reliable way to call the 
        ##     __init__ method from Employee's 'super Class' 
        ##      Person (including name and pet)

        super(Employee, self).__init__(name)

        ## Employee has-a salary
        self.salary = salary

## Fish is-a Object
class Fish(object):
    pass

## Salmon is-a Fish
class Salmon(Fish):
    pass

## Halibut is-a Fish
class Halibut(Fish):
    pass


## rover is-a Dog (with name 'Rover')
rover = Dog("Rover")

## satan is-a Cat (with name 'Satan')
satan = Cat("Satan")

## mary is-a Person (with name 'Mary')
mary = Person("Mary")

## mary has-a pet called satan.
mary.pet = satan

## frank is-a Employee with name "Frank" and salary 120000.
## Note: Because Employee is-a Person, frank falls under the 
## Person class too.
frank = Employee("Frank", 120000)

## frank (the Employee from above) has a pet named rover. Since 
## frank is-a Employee, which falls under (is-a) Person, this means 
## he has-a pet as well.
frank.pet = rover

## flipper is-a Fish
flipper = Fish()

## course is-a Salmon
crouse = Salmon()

## harry is-a Halibut
harry = Halibut()
4

你已经很接近了。我记得我刚开始学习面向对象编程(OOP)的时候也很挣扎,尤其是在学了一些C语言之后。其实,面向对象编程比看起来要简单得多……这里唯一有点难的是第一个概念,就是你提到的……动物是一个对象。

虽然你说得对,狗、猫和员工都是对象,但更重要的是,它们分别是动物、动物和人。

这个练习其实是关于面向对象编程的一个特性,叫做继承。比如,狗的类层次结构是这样的:

对象 -> 动物 -> 狗

一只狗既是动物也是对象,它“拥有”这两者的所有属性。现在,这些属性可以在子类中被重写,但那是后面再讨论的内容。

我觉得你在“比目鱼”和“鲑鱼”那部分开始理解这个概念了。它们都是对象,也是鱼。

最后我想说的是:

弗兰克是一个员工(同时也是一个人和对象),他的名字是弗兰克,薪水是120000。

希望这些能帮到你。

撰写回答