首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >面向对象编程基础:继承和隐藏(Python)

面向对象编程基础:继承和隐藏(Python)
EN

Stack Overflow用户
提问于 2010-09-26 22:22:35
回答 4查看 1.5K关注 0票数 1

级别:初学者

我正在做我的面向对象编程的第一步。代码的目的是展示方法是如何在链中向上传递的。因此,当我调用UG.say(person, 'but i like')时,say方法被指示调用类MITPerson。鉴于MITPerson不包含say方法,它将把它向上传递给Person类。我认为代码没有问题,因为它是讲座的一部分(参见下面的源码)。我认为是我在运行代码时遗漏了定义某些东西。但不确定是什么。我认为作为第一个参数的错误消息寻找的UG instance引用了self,但原则上不需要提供,对吗?有什么提示吗?

代码语言:javascript
复制
class Person(object):
    def __init__(self, family_name, first_name):
        self.family_name = family_name
        self.first_name = first_name
    def familyName(self):
        return self.family_name
    def firstName(self):
        return self.first_name
    def say(self,toWhom,something):
        return self.first_name + ' ' + self.family_name + ' says to ' +   toWhom.firstName() + ' ' + toWhom.familyName() + ': ' + something


class MITPerson(Person):
    def __init__(self, familyName, firstName):
        Person.__init__(self, familyName, firstName)


class UG(MITPerson):
    def __init__(self, familyName, firstName):
        MITPerson.__init__(self, familyName, firstName)
        self.year = None
    def say(self,toWhom,something):
        return MITPerson.say(self,toWhom,'Excuse me, but ' + something)



>>> person = Person('Jon', 'Doe')
>>> person_mit = MITPerson('Quin', 'Eil')
>>> ug = UG('Dylan', 'Bob')
>>> UG.say(person, 'but i like')


    UG.say(person, 'bla')
**EDIT (for completeness)**: it should say UG.say(person, 'but i like') #the 'bla' creeped in from a previous test
TypeError: unbound method say() must be called with UG instance as first argument (got Person instance instead)

来源:麻省理工学院OpenCourseWare http://ocw.mit.edu计算机科学与编程入门2008秋季

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-09-26 22:35:30

您正在调用类而不是实例。

代码语言:javascript
复制
>>> ug = UG('Dylan', 'Bob')
>>> UG.say(person, 'but i like')


UG.say(person, 'bla')

改为调用实例

代码语言:javascript
复制
>>> ug = UG('Dylan', 'Bob')
>>> ug.say(person, 'but i like')
票数 4
EN

Stack Overflow用户

发布于 2010-09-26 23:09:19

答案很好,但我认为有一个附注是很重要的。获取代码片段(在MITPerson类中):

代码语言:javascript
复制
def __init__(self, familyName, firstName):
    Person.__init__(self, familyName, firstName)

这段代码完全没有用,而且是多余的。当子类不需要在其超类的方法实现中重写任何内容时,子类看起来像是“重写”该方法是完全没有用的……然后将所有工作委托给超类,而不做任何更改。

完全没有目的,永远不会有任何影响的代码(除了略微降低整个系统的速度),因此可以不受任何伤害地删除的代码应该被删除:为什么要把它放在那里?!程序中存在的任何代码都不可避免地会损害程序的质量:这种无用的“镇流器”稀释了有用的、有效的代码,使程序更难阅读、维护和调试,等等。

大多数人似乎在大多数情况下都直观地理解了这一点(因此,您看不到许多“伪覆盖”大多数方法的代码,但在方法体中,它们只是指向超类实现),除了__init__ --由于某种原因,许多人似乎有一个心理盲点,只是看不到与其他方法完全相同的规则。这种盲点可能来自于熟悉其他完全不同的语言,在这些语言中,规则不适用于类的构造函数,再加上将__init__视为实际上不是的构造函数(它是一个初始化器)的误解。

所以,总而言之:一个子类应该定义__init__当且仅当它需要在超类自己的初始化器之前或之后,或者在它自己的初始化器之前和之后做一些其他的事情(很少它可能想要做一些而不是,即而不是委托给超类初始化器,但这几乎不是一个好的做法)。如果子类的__init__主体的只是了一个对超类的__init__的调用,并以相同的顺序使用完全相同的参数,那么从代码中删除子类的__init__ (就像您对任何其他类似冗余的方法所做的那样)。

票数 3
EN

Stack Overflow用户

发布于 2010-09-26 22:31:20

变化

代码语言:javascript
复制
UG.say(person, 'but i like')

代码语言:javascript
复制
ug.say(person, 'but i like')

UG.say返回未绑定的方法say。“未绑定”意味着不会自动填充say的第一个参数。未绑定的方法say有3个参数,第一个参数必须是UG的实例。相反,UG.say(person, 'but i like')Person的一个实例作为第一个参数发送。这解释了Python给出的错误消息。

相反,ug.say返回绑定的方法say。"Bound“意味着要说的第一个参数将是ug。绑定方法有两个参数:toWhomsomething。因此,ug.say(person, 'but i like')的工作方式与预期一致。

unbound method has been removed from Python3的概念。相反,UG.say只返回一个函数,该函数(仍然)需要3个参数。唯一的区别是不再对第一个参数进行类型检查。但是,您仍然会得到一个错误,只是一个不同的错误:

代码语言:javascript
复制
TypeError: say() takes exactly 3 positional arguments (2 given)

PS。当开始学习Python时,我想我只是尝试接受UG.say返回一个未绑定的方法(期望3个参数),而ug.say是调用一个方法(期望2个参数)的正常方式。稍后,要真正了解attribute lookup如何实现这种行为差异(同时保持相同的限定名语法),您需要研究descriptors和Python的规则。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3798194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档