初学 Python ,学习到 Python 继承,觉得继承/多态在 Python 中基本是废的,麻烦大家帮我解惑, 非常感谢大家!下附疑惑代码

2017-02-04 16:27:57 +08:00
 palmers

代码如下:

class Student(object):
    def __init__(self,name,age,school):
        self.__name = name
        self.__age = age
        self.__school = school

    def toString(self):
        print('我是%s,我%s 岁了,在%s 上学.' %(self.__name,self.__age,self.__school))


class XiaoMing(Student):
    def __init__(self,name,age,school):
        self.__name = name
        self.__age = age
        self.__school = school

    ''' 覆写父类 toString()方法'''
    # def toString(self):
    #     print('我是%s,我%s 岁了,在%s 上学.' %(self.__name,self.__age,self.__school))
''' 接受 Student 任何子类对象'''
def fun(stu):
    stu.toString()

###测试
xm = XiaoMing('小明',25,'北大')
fun(xm) 

按照继承, XiaoMing继承自 Student, 且属性是一模一样的,则toString函数再写一遍是多余的, 道理讲,应该直接使用父类的 toString方法,就可以了, 但是我去掉XiaoMingtoString方法后,就找不到 自身实例的私有属性了, 因为 python 解释器将私有属性名改变了, 我就觉得在这里多态基本都是废的, 代码复用完全无效了,

顺便问下大家, 继承/多态 在python中还有那些有用的地方?

5894 次点击
所在节点    Python
42 条回复
arischow
2017-02-04 16:32:49 +08:00
你这里为什么要重写一次 XiaoMing 的 __init__?

如果你必须重写 __init__,还可以看下这个:
http://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html
palmers
2017-02-04 16:39:27 +08:00
@arischow 咦??可以不写这个构造方法吗? 我试试 我还不知道这个啊  谢谢!!~  我看看你给的链接
cszeus
2017-02-04 16:50:05 +08:00
class XiaoMing(Student):
def __init__(self,name,age,school):
Student.__init__(self, name, age, school)
ijustdo
2017-02-04 16:56:28 +08:00
def __str__(self):
return '我是%s,我%s 岁了,在%s 上学.' %(self.__name,self.__age,self.__school)

看代码 你 toString 也多余 一般都直接 __str__

然后你 str(实例)或者 print 实例 看看呢
palmers
2017-02-04 16:58:30 +08:00
@arischow 尝试了几次不知道怎么写 你能代码展示下吗? 谢谢了
dwood
2017-02-04 16:59:06 +08:00
楼主这是用父类的来访问子类的成员变量了。其他语言也不是这么继承的吧…子类需要调用父类的构造函数。
palmers
2017-02-04 17:00:36 +08:00
@cszeus 不行 还是提示 `AttributeError: 'XiaoMing' object has no attribute '_Student__name'`
arischow
2017-02-04 17:01:43 +08:00
@palmers 满足你需求的话,直接给 class 写个 pass 就好了?
chris5641
2017-02-04 17:02:11 +08:00
class XiaoMing(Student):
def __init__(self,name,age,school):
super().__init__(name,age,school)
palmers
2017-02-04 17:02:38 +08:00
@ijustdo 恩恩 我这个只是用来测试的  继承子类覆盖父类方法  按照道理,子类没有父类有就可以了,一样可以调用的
palmers
2017-02-04 17:03:35 +08:00
@chris5641 这种我尝试过了 不行的
palmers
2017-02-04 17:06:12 +08:00
@arischow   1#说不写构造 我就尝试了直接 pass 不行的, 我想的是, 子类如果要编写一个和父类一模一样的方法, 那子类应该就不用再重复编写了, 至于 self 应该在传递 xm 的时候就应该指向 xm 对象才对的 ,但是 根据错误提示 还是指向了 Student 对象了
chris5641
2017-02-04 17:12:35 +08:00
LZ 你的命名有问题,如果一般的私有变量用一个下划线,两个下划线的变量通过继承是无法被覆盖的

http://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p05_encapsulating_names_in_class.html
dwood
2017-02-04 17:13:38 +08:00
用的 python2 吧, super(Student,self).__init__(name,age,school)。
palmers
2017-02-04 17:20:14 +08:00
@chris5641 但是使用单下滑下[_]就变成 public 了.
palmers
2017-02-04 17:20:51 +08:00
@dwood 是 Python 3.6.0
dwood
2017-02-04 17:26:56 +08:00
那 def __init__(self,name,age,school):
super().__init__(name, age, school) 这样写没问题啊。
Allianzcortex
2017-02-04 19:02:34 +08:00
@palmers pip 和 virtualenv 的作者说: Never, ever use two leading underscores.This is annoying private. 所以这个就别管 PEP8 了,@kennethreitz 写的代码都是用单下划线。 Py3.5+ 后用 super().__init__(*args,**kwargs) 来做到多继承。还有.......toString()......我猜有 Java/Scala 背景?
phithon
2017-02-04 19:08:33 +08:00
django 选手表示,多继承撑起了 class based view 的一片天……
登录验证只需继承一个 LoginRequiredMixin ,需要表单的话再继承一下 FormMixin ,需要模板的话再继承一下 TemplateResponseMixin ,然后选择一个基本父类比如 View 、 ProcessFormView 即可完成一个 view 的编写。
剩下的事就是写写这些父类必须的属性即可,代码量能压缩到最少。
Allianzcortex
2017-02-04 19:12:19 +08:00
@phithon 嗯, Mixin 和 CBVS 是绝配啊,避免了引入多个 utils 函数的烦恼。但我用的最多的还是 FBVS ⊙﹏⊙b 。。。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/338062

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX