Crossin的编程教室

标题: 【Python 第50课】 面向对象(4) [打印本页]

作者: crossin先生    时间: 2013-8-12 17:54
标题: 【Python 第50课】 面向对象(4)
上一课举了一个面向对象和面向过程相比较的例子之后,有些同学表示,仍然没太看出面向对象的优势。没关系,那是因为我们现在接触的程序还不够复杂,等以后你写的程序越来越大,就能体会到这其中的差别了。

今天我们就来举一个稍稍再复杂一点的例子。

仍然是从A地到B地,这次除了有汽车,我们还有了一辆自行车!
自行车和汽车有着相同的属性:速度(speed)。还有一个相同的方法(drive),来输出行驶/骑行一段距离所花的时间。但这次我们要给汽车增加一个属性:每公里油耗(fuel)。而在汽车行驶一段距离的方法中,除了要输出所花的时间外,还要输出所需的油量。

面向过程的方法,你可能需要写两个函数,然后把数据作为参数传递进去,在调用的时候要搞清应该使用哪个函数和哪些数据。有了面向对象,你可以把相关的数据和方法封装在一起,并且可以把不同类中的相同功能整合起来。这就需要用到面向对象中的另一个重要概念:继承。

我们要使用的方法是,创建一个叫做Vehicle的类,表示某种车,它包含了汽车和自行车所共有的东西:速度,行驶的方法。然后让Car类和Bike类都继承这个Vehicle类,即作为它的子类。在每个子类中,可以分别添加各自独有的属性。

Vehicle类被称为基本类或超类,Car类和Bike类被成为导出类或子类。
  1. class Vehicle:
  2.     def __init__(self, speed):
  3.         self.speed = speed

  4.     def drive(self, distance):
  5.         print 'need %f hour(s)' % (distance / self.speed)

  6. class Bike(Vehicle):
  7.     pass

  8. class Car(Vehicle):
  9.     def __init__(self, speed, fuel):
  10.         Vehicle.__init__(self, speed)
  11.         self.fuel = fuel

  12.     def drive(self, distance):
  13.         Vehicle.drive(self, distance)
  14.         print 'need %f fuels' % (distance * self.fuel)

  15. b = Bike(15.0)
  16. c = Car(80.0, 0.012)
  17. b.drive(100.0)
  18. c.drive(100.0)
复制代码
解释一下代码:
__init__函数会在一个实例被创建的时候自动调用,用来初始化类。它的参数,要在创建实例的时候提供。于是我们通过提供一个数值来初始化speed的值。

class定义后面的括号里表示这个类继承于哪个类。Bike(Vehicle)就是说Bike是继承自Vehicle中的子类。Vehicle中的属性和方法,Bike都会有。因为Bike不需要有额外的功能,所以用pass在类中保留空块,什么都不用写。

Car类中,我们又重新定义了__init__和drive函数,这样会覆盖掉它继承自Vehicle的同名函数。但我们依然可以通过“Vehicle.函数名”来调用它的超类方法。以此来获得它作为Vehicle所具有的功能。注意,因为是通过类名调用方法,而不是像之前一样通过对象来调用,所以这里必须提供self的参数值。在调用超类的方法之后,我们又给Car增加了一个fuel属性,并且在drive中多输出一行信息。

最后,我们分别创建一个速度为15的自行车对象,和一个速度为80、耗油量为0.012的汽车,然后让它们去行驶100的距离。

50class.png

#==== Crossin的编程教室 ====#
微信ID:crossincode
论坛:http://crossin.me
QQ群:312723402

面向零基础初学者的编程课
每天5分钟,轻松学编程



作者: crossin先生    时间: 2013-8-12 23:15
多说一句,__init__函数是左右各两个下划线。这是python系统定义的名称。其他还有很多系统定义的方法和属性也是用双下划线包围的。
作者: 匠逍之岿    时间: 2013-8-29 16:40
最后一段代码中,b = Bike(15.0)  和 c = Car(80.0,0.012),类Bike和类Car都继承类Vehicle,但是Vehicle里有两个方法啊,怎么确定括号里的参数15.0 和 80.0   0.012 是哪个方法里的参数?
作者: crossin先生    时间: 2013-8-29 16:59
匠逍之岿 发表于 2013-8-29 16:40
最后一段代码中,b = Bike(15.0)  和 c = Car(80.0,0.012),类Bike和类Car都继承类Vehicle,但是Vehicle里 ...

Bike没有重写Vehicle的__init__函数,所以它会调用它基类的。Car重写了,所以会调用它自身的。假如Car里要调用Vehicle中的同名方法,要用Vehicle.__init__()
作者: 匠逍之岿    时间: 2013-8-29 17:08
还有__init__是什么?为什么要用这个名字?  初始化类是什么意思?不太懂...
作者: crossin先生    时间: 2013-8-29 17:14
匠逍之岿 发表于 2013-8-29 17:08
还有__init__是什么?为什么要用这个名字?  初始化类是什么意思?不太懂...

当创建一个类的实例时,有很多工作要做,比如类中的一些变量要赋给初始值。__init__就是干这种事。它会在一个实例被创建的时候自动调用。前后两个双下划线是系统方法的命名方式,它是python命名的,不需要你手动去调用
作者: lsxx043    时间: 2013-8-31 13:21
为什么要用__init__,有什么好处,这个函数也可以比不用__init__,直接def drive(self,speed,distance)
作者: lsxx043    时间: 2013-8-31 13:33
另外def drive的函数中间,为什么一定要distance/self.speed,而不是直接distance/speed,speed不是已经定义过了吗
作者: lsxx043    时间: 2013-8-31 13:35
而且,distance又为何不建立一个def __init__()?
作者: crossin先生    时间: 2013-9-1 00:33
lsxx043 发表于 2013-8-31 13:21
为什么要用__init__,有什么好处,这个函数也可以比不用__init__,直接def drive(self,speed,distance) ...

init是去初始化类,我们假设speed是vehicle的属性,所以应该在建立的时候被创建。直接那样当然可以实现统一的效果,但你每次都需要指定speed,这就失去面向对象的意义了
作者: crossin先生    时间: 2013-9-1 00:33
lsxx043 发表于 2013-8-31 13:33
另外def drive的函数中间,为什么一定要distance/self.speed,而不是直接distance/speed,speed不是已经定 ...

如果不加self,那speed就只是drive函数中的一个局部变量
作者: crossin先生    时间: 2013-9-1 00:34
lsxx043 发表于 2013-8-31 13:35
而且,distance又为何不建立一个def __init__()?

distance只是个变量,不是类。
作者: fptxyy    时间: 2014-4-3 16:44
老师,
我写的代码与您一样,可是运行到,class Bike(Vehicel):就出问题了。代码及问题如下:
# -*- coding: cp936 -*-
class Vehicle:
    def _init_(self,speed):
        self.speed=speed
        
    def drive(self,distance):
        print"need %f hours(s)" %(distance/self.speed)

class Bike(Vehicel):
    pass

class Car(Vehicle):
    def _init_(self,speed,fuel):
        Vehicle._init_(self,speed)
        self.fuel=fuel

    def drive(self,distance):
        Vehicle.drive(self,distance)
        print"need %f fuels"%(distance*self.fuel)

b=Bike(15.0)
c=Car(80.0,0.012)
b.drive(100.0)
c.drive(100.0)
--
>>> = RESTART =
>>>

Traceback (most recent call last):
  File "C:/Python27/作业题/lesson50class.py", line 9, in <module>
    class Bike(Vehicel):
NameError: name 'Vehicel' is not defined
>>> 是怎么回事呢,恳请老师解答~


作者: crossin先生    时间: 2014-4-3 17:39
fptxyy 发表于 2014-4-3 16:44
老师,
我写的代码与您一样,可是运行到,class Bike(Vehicel):就出问题了。代码及问题如下:
# -*- coding ...

你拼成了 Vehicel
作者: fptxyy    时间: 2014-4-7 10:00
本帖最后由 fptxyy 于 2014-4-7 10:04 编辑
crossin先生 发表于 2014-4-3 17:39
你拼成了 Vehicel


是啊,感谢老师!真是太惭愧了, 竟然没看出来  
送花 * * *
作者: 脑子有音乐    时间: 2014-6-27 18:19
class Car(Vehicle):
    def __init__(self, speed, fuel):
        Vehicle.__init__(self, speed)
        self.fuel = fuel

-----------------------------------------------
这一块是重新定义了__init__()这个函数
但是它里面的变量继承了Vehicle的speed变量的熟悉,对吗?
------------------------------------------------
为什么要重新定义__init__和drive函数?
作者: crossin先生    时间: 2014-6-28 17:00
脑子有音乐 发表于 2014-6-27 18:19
class Car(Vehicle):
    def __init__(self, speed, fuel):
        Vehicle.__init__(self, speed)

因为作为子类,有自己专属的__init__方法和drive方法,不能直接套用父类的
作者: 脑子有音乐    时间: 2014-6-28 19:48
crossin先生 发表于 2014-6-28 17:00
因为作为子类,有自己专属的__init__方法和drive方法,不能直接套用父类的

speed可以继承,但__init__方法和drive()方法不能继承,这个有点搞不懂了
作者: crossin先生    时间: 2014-6-30 17:23
脑子有音乐 发表于 2014-6-28 19:48
speed可以继承,但__init__方法和drive()方法不能继承,这个有点搞不懂了

speed也被重新赋值了。如果不去碰speed,那它就会和它的父类一样
作者: 萧风    时间: 2014-7-3 09:32
本帖最后由 萧风 于 2014-7-3 09:34 编辑
  1. class Vehicle:
  2.     def __init__(self,speed):                  #为什么这里有__init__,后面的drive没有?init函数有什么作用?
  3.         self.speed=speed                            #为什么要有self.speed=speed?        
  4.                                                                #请老师讲的直白一些,前面的那些回复我没看懂

  5.     def drive(self,distance):
  6.         print"need %f hours"%(distance/self.speed)
  7. class Bike(Vehicle):
  8.     pass

  9. class Car(Vehicle):
  10.     def __init__(self,speed,fuel):
  11.         Vehicle.__init__(self,speed)
  12.         self.fuel=fuel

  13.     def drive(self,distance):
  14.         Vehicle.drive(self,distance)
  15.         print"need %f fuels"%(distance*self.fuel)


  16. b=Bike(15.0)
  17. c=Car(80.0,0.012)
  18. b.drive(100.0)
  19. c.drive(100.0)
复制代码

作者: 萧风    时间: 2014-7-3 09:45
crossin先生 发表于 2013-9-1 00:33
如果不加self,那speed就只是drive函数中的一个局部变量

这个有什么影响?
作者: 萧风    时间: 2014-7-3 09:45
crossin先生 发表于 2013-9-1 00:34
distance只是个变量,不是类。

没懂
作者: crossin先生    时间: 2014-7-3 15:01
萧风 发表于 2014-7-3 09:45
没懂

这个我无法一两句给你简单形象的解释了。
建议你去找本系统的编程书籍看一看面向对象的介绍。
作者: QQ_E29166    时间: 2014-7-29 22:58
class Vehicle:
    def __init__(self, speed):
        self.speed = speed
     #赋值函数,将成员变量值speed(抽象的、任何机器的speed)赋给函数内实际调用值self.speed(函数内真正用到的某个机器的speed),以便下面的函数调用(成员函数里的变量都是特指的某个具体的变量,用self.开头)
    def drive(self, distance):
        print 'need %f hour(s)' % (distance / self.speed)
  #这个是个类里面的成员函数,计算功能
class Bike(Vehicle):
    pass
#完全继承,不用改动

class Car(Vehicle):
    def __init__(self, speed, fuel):
        Vehicle.__init__(self, speed)
        self.fuel = fuel
   赋值函数,在继承vehicle的基础上,Vehicle.__init__(self, speed)是继承过来的,多加了个fuel,同样把fuel值赋给self。fuel以备调用
    def drive(self, distance):
        Vehicle.drive(self, distance)
        print 'need %f fuels' % (distance * self.fuel)
#成员函数,按规则计算功能,除了按vehicle的规则计算用时外,加入了新规则计算油耗(这里用到了self.fuel值)。
b = Bike(15.0)
c = Car(80.0, 0.012)
b.drive(100.0)
c.drive(100.0)
计算结果是三个。
这个面向对象的程序,简单来讲就是指定一个公用的类,设定变量(包括类成员变量,实际计算调用具体变量),制定规则(应用成员函数)
   这是我个人的理解。
                   -------------------------------------------------鹰隼
作者: liu-pengfei    时间: 2014-9-26 00:39
是不是每次生成对象的时候,b = Bike(15.0),会首先自动调用,def __init__(self, speed):
        self.speed = speed,这个方法,把15.0自动赋值给了speed,这个对象就有了speed的值。
作者: crossin先生    时间: 2014-9-26 10:41
liu-pengfei 发表于 2014-9-26 00:39
是不是每次生成对象的时候,b = Bike(15.0),会首先自动调用,def __init__(self, speed):
        self.sp ...

是的
作者: zzxomg    时间: 2015-3-20 17:09
  1. #coding:gbk
  2. #练习类的建立
  3. class vehicle():
  4. #构造方法
  5.                 def __init__(self,speed):
  6.                                 self.speed = speed
  7. #驾驶方法
  8.                 def drive(self,distance):
  9.                                 time = distance/self.speed
  10.                                 print '需要的驾驶时间是:%d'%time
  11. #自行车
  12. class Bike(vehicle):
  13.                 pass
  14. #汽车
  15. class Car(vehicle):
  16.                 def __init__(self,speed,fuel):
  17.                                 vehicle.__init__(self,speed)
  18.                                 self.fuel = fuel
  19.                 def drive(self,distance):
  20.                                 vehicle.drive(self,distance)
  21.                                 fuelcount = distance/100*self.fuel
  22.                                 print '您开的是汽车,需要耗油%d升'%(fuelcount)
  23.        
  24. #测试-------------
  25. bike = Bike(2)
  26. bike.drive(100)
  27. car = Car(100,7)
  28. car.drive(100)
复制代码

作者: 草办    时间: 2015-12-10 17:20
get
作者: 周末晒被子    时间: 2015-12-17 00:40
本帖最后由 周末晒被子 于 2015-12-17 00:49 编辑

先生,我对__init__函数还是有点疑问,我试着在49课的例子改一下:

class Car:
    def _init_(self,speed):
        self.speed=speed
   
    def drive(self, distance):
        time = distance / self.speed
        print time

car1 = Car(30)                      #就是这一行报错了
car1.speed = 60.0
car1.drive(100.0)
car1.drive(200.0)

报错:TypeError: this constructor takes no arguments  为什么呢

这两天因为课程有点难,有点畏惧,但是我并不是天才啊,难就难吧。感谢先生这么良心的课程。
作者: crossin先生    时间: 2015-12-17 14:19
周末晒被子 发表于 2015-12-17 00:40
先生,我对__init__函数还是有点疑问,我试着在49课的例子改一下:

class Car:

__init__是两个下划线,内置函数都是两个下划线
作者: 周末晒被子    时间: 2015-12-17 15:08
crossin先生 发表于 2015-12-17 14:19
__init__是两个下划线,内置函数都是两个下划线

嗯...沙发就有说,但我对“__init__是两个下划线”的“两个”理解成,一边一个一共两个...
作者: 周末晒被子    时间: 2015-12-17 15:14
crossin先生 发表于 2014-6-28 17:00
因为作为子类,有自己专属的__init__方法和drive方法,不能直接套用父类的

子类Bike(Vehicle))应该是直接套用了父类吧?
不能直接套用父类,是当,子类需要有自己的专属的方法时,才这么说的吧。

作者: crossin先生    时间: 2015-12-17 22:10
周末晒被子 发表于 2015-12-17 15:14
子类Bike(Vehicle))应该是直接套用了父类吧?
不能直接套用父类,是当,子类需要有自己的专属的方法时, ...

继承父类
作者: catherinemic    时间: 2016-1-29 10:50
get it!
论坛的形式很好,看了大家的讨论,又会多一些理解~~
作者: fangweiren    时间: 2016-2-2 14:55
这个面向对象看的不太懂,继续学习
  1. # -*- coding: UTF-8 -*-
  2. class Vehicle:
  3.         def __init__(self,speed):
  4.                 self.speed = speed
  5.                
  6.         def drive(self,distance):
  7.                 print 'need %f hour(s)' %(distance / self.speed)
  8.                
  9. class Bike(Vehicle):
  10.         pass

  11. class Car(Vehicle):
  12.         def __init__(self,speed,fuel):
  13.                 Vehicle.__init__(self,speed)
  14.                 self.fuel = fuel
  15.                
  16.         def drive(self,distance):
  17.                 Vehicle.drive(self,distance)
  18.                 print 'need %f fuels' % (distance * self.fuel)
  19.                
  20. b = Bike(15.0)
  21. c = Car(80.0,0.012)
  22. b.drive(100.0)
  23. c.drive(100.0)
复制代码

作者: 弹星者    时间: 2016-3-13 09:19
本帖最后由 弹星者 于 2016-3-13 09:26 编辑
  1. class Vehicle:
  2.     def __init__(self, speed):
  3.         self.speed = speed

  4.     def drive(self, distance):
  5.         print 'need %f hour(s)' % (distance / self.speed)

  6. class Bike(Vehicle):
  7.     pass

  8. class Car(Vehicle):
  9.     def __init__(self, speed, fuel):
  10.         Vehicle.__init__(self, speed)
  11.         self.fuel = fuel

  12.     def drive(self, distance):
  13.         Vehicle.drive(self, distance)
  14.         print 'need %f fuels' % (distance * self.fuel)

  15. b = Bike(15.0)
  16. c = Car(80.0, 0.012)
  17. b.drive(100.0)
  18. c.drive(100.0)

  19. d=Car(80,None)
  20. d.Vehicle.drive(100)

  21. #下面是运行报错
  22. '''
  23. need 6.666667 hour(s)
  24. need 1.250000 hour(s)
  25. need 1.200000 fuels
  26. <blockquote>Traceback (most recent call last):
复制代码
在crossin老师代码的最后添加了两行,想尝试一下子类调用父类里的函数,然而运行的时候报错了,这个错误为什么呀(代码复制的时候没复制好,在楼下重发一个
作者: 弹星者    时间: 2016-3-13 09:27
  1. class Vehicle:
  2.     def __init__(self, speed):
  3.         self.speed = speed

  4.     def drive(self, distance):
  5.         print 'need %f hour(s)' % (distance / self.speed)

  6. class Bike(Vehicle):
  7.     pass

  8. class Car(Vehicle):
  9.     def __init__(self, speed, fuel):
  10.         Vehicle.__init__(self, speed)
  11.         self.fuel = fuel

  12.     def drive(self, distance):
  13.         Vehicle.drive(self, distance)
  14.         print 'need %f fuels' % (distance * self.fuel)

  15. b = Bike(15.0)
  16. c = Car(80.0, 0.012)
  17. b.drive(100.0)
  18. c.drive(100.0)

  19. d=Car(80,None)
  20. d.Vehicle.drive(100)

  21. #下面是报错
  22. '''
  23. need 6.666667 hour(s)
  24. need 1.250000 hour(s)
  25. need 1.200000 fuels
  26. Traceback (most recent call last):
  27.   File "123.py", line 26, in <module>
  28.     d.Vehicle.drive(100)
  29. AttributeError: Car instance has no attribute 'Vehicle'
  30. '''
复制代码
在crossin老师代码的最后添加了两行,想尝试一下子类调用父类里的函数,然而运行的时候报错了,这个错误为什么呀
作者: crossin先生    时间: 2016-3-14 12:40
弹星者 发表于 2016-3-13 09:27
在crossin老师代码的最后添加了两行,想尝试一下子类调用父类里的函数,然而运行的时候报错了,这个错误为 ...

没有这种语法。

一般不会这么用。如果硬要对一个子类对象去调用它被覆盖的父类方法,那首先,它的父类要继承自object:
  1. class Vehicle(obect):
  2. ...
复制代码
然后写成:
  1. super(Car, d).drive(100)
复制代码

作者: exchen    时间: 2016-4-13 11:06
不懂就一点speed在整个程序中的作用是什么
作者: crossin先生    时间: 2016-4-13 21:16
exchen 发表于 2016-4-13 11:06
不懂就一点speed在整个程序中的作用是什么

self.speed,这里speed就是对象的成员变量,是这个对象独有的属性
作者: kuaikemai    时间: 2016-6-3 13:19
老师,有两个问题:
1.
b = Bike(15.0)
c = Car(80.0, 0.012)
这里两行代码是不是是由:
b=Bike()
b.Bike=15.0
这样类似的缩写而来的?
2.
我看到之前的课没有初始化函数,在相应的地方您用的:
class Car:
    speed = 0
这样的效果是一样的吗,还是说之后复杂的程序会还是用__init__函数好些

谢谢老师
作者: crossin先生    时间: 2016-6-3 13:45
kuaikemai 发表于 2016-6-3 13:19
老师,有两个问题:
1.
b = Bike(15.0)

效果类似,但不是缩写。如你所说,__init__这么定义了,所以必须在初始化的时候给。从规范上来说,一个东西如果有一个必须得在一开始就设定的属性,那应该初始化就给。不然别人用你的类的时候,可能并不知道还必须要给这个值
作者: l0ve1o24    时间: 2017-1-12 16:14
class Car(Vehicle):
    def __init__(self, speed, fuel):
        Vehicle.__init__(self, speed)
        self.fuel = fuel
老师,这段里Vehicle.__init__(self, speed) 改成self.speed = speed
好像更好理解
  1. class Vehicle:
  2.     def __init__(self, speed):
  3.         self.speed = speed

  4.     def drive(self, distance):
  5.         print 'need %f hour(s)' % (distance / self.speed)

  6. class Bike(Vehicle):
  7.     pass

  8. class Car(Vehicle):
  9.     def __init__(self, speed, fuel):
  10.         self.speed = speed
  11.         self.fuel = fuel

  12.     def drive(self, distance):
  13.         Vehicle.drive(self, distance)
  14.         print 'need %f fuels' % (distance * self.fuel)

  15. b = Bike(15.0)
  16. c = Car(80.0, 0.012)
  17. b.drive(100.0)
  18. c.drive(100.0)
复制代码

作者: crossin先生    时间: 2017-1-12 17:45
l0ve1o24 发表于 2017-1-12 16:14
class Car(Vehicle):
    def __init__(self, speed, fuel):
        Vehicle.__init__(self, speed)

效果一样,但你这个就没有调用父类方法了。等于完全抛弃了原有的代码
作者: l0ve1o24    时间: 2017-1-13 12:36
crossin先生 发表于 2017-1-12 17:45
效果一样,但你这个就没有调用父类方法了。等于完全抛弃了原有的代码

恩,谢谢老师
作者: nic8523    时间: 2017-7-11 16:59
请问 Bike类中的pass是一个关键字吗?可以不写这个pass吗?
作者: crossin先生    时间: 2017-7-11 22:57
nic8523 发表于 2017-7-11 16:59
请问 Bike类中的pass是一个关键字吗?可以不写这个pass吗?

是个关键字,不写的话这里就空了,那会报错。pass就是什么也不做,但保证程序的结构完整
作者: z850672062    时间: 2017-11-4 14:55
class Car(Vehicle):
    def __init__(self, speed, fuel):
        Vehicle.__init__(self, speed)
        self.fuel = fuel

    def dirve(self, distance):
        Vehicle.driver(self, distance)
        print('need %f fuels' % (distance * self.fuel))

b = Bike(15.0)
c = Car(80.0,0.012)
b.drive(100.0)
c.drive(100.0)

先生 我Car类里面的drive写成了 dirve 然后在下面的c.drive(100.0)还是成功的输出了
need 6.666667 hour(s)
need 1.250000 hour(s)
刚开始我想了半天
怎么下行print没输出来。。   然后又重新写了下代码才发现
现在又想想为什么代码没报错呢   我的Car里没drive方法啊

作者: z850672062    时间: 2017-11-4 15:00
z850672062 发表于 2017-11-4 14:55
class Car(Vehicle):
    def __init__(self, speed, fuel):
        Vehicle.__init__(self, speed)

是不是因为继承了父类

所以c.drive(100.0) 调用的是父类(超类)的 drive方法
作者: crossin先生    时间: 2017-11-4 15:27
z850672062 发表于 2017-11-4 15:00
是不是因为继承了父类

所以c.drive(100.0) 调用的是父类(超类)的 drive方法

是呀
作者: Selvaria    时间: 2017-11-15 14:27
class Vehicle(object):
    def __init__(self,speed):
        self.speed = speed

class Car(Vehicle):
    def __init__(self, speed, distance, oil_spent):
        Vehicle.__init__ = speed
        self.distance = distance
        self.oil_spent = oil_spent
    def cost(self):
        f = self.distance * self.oil_spent
        print('we need %s fuels' %f)

class Bike(Vehicle):
    pass

bike = Bike(40)
car = Car(80,100,0.012)
print(car.cost)

我是自己写的,为什么我只能查到一大串内存值,像这样:
<bound method Car.cost of <__main__.Car object at 0x0173ABD0>>
作者: crossin先生    时间: 2017-11-15 19:32
Selvaria 发表于 2017-11-15 14:27
class Vehicle(object):
    def __init__(self,speed):
        self.speed = speed

cost是函数,后面的括号呢
看下函数那几课
作者: Selvaria    时间: 2017-11-16 08:41
crossin先生 发表于 2017-11-15 19:32
cost是函数,后面的括号呢
看下函数那几课

嗯,谢谢。后来自己也发现了。但是执行后会多一行结果None,这是为啥
作者: crossin先生    时间: 2017-11-16 09:04
Selvaria 发表于 2017-11-16 08:41
嗯,谢谢。后来自己也发现了。但是执行后会多一行结果None,这是为啥

你没有 return
看下函数的返回值那课
作者: Selvaria    时间: 2017-11-16 17:07
crossin先生 发表于 2017-11-16 09:04
你没有 return
看下函数的返回值那课

谢谢,但以前一直没注意到这个问题,比如:
def isequal(x,y):
    if x == y:
        print('Equal!')
    else:
        print('Not eaqual')
我没有写return,执行后也并未出现None值
>>> isequal(1,2)
Not eaqual
>>> isequal(2,2)
Equal!
作者: crossin先生    时间: 2017-11-17 10:04
Selvaria 发表于 2017-11-16 17:07
谢谢,但以前一直没注意到这个问题,比如:
def isequal(x,y):
    if x == y:

因为你没有另外 print 函数的值
作者: Charlene97    时间: 2018-1-22 04:31
非常感谢crossin老师! 很多原本自己不懂的问题原来大家也有, 谢谢老师耐心解答~!

P.S. 希望大家以后问问题可以有礼貌一点!! 很多人都没说谢谢, 有些话语还过于直接. crossin老师在很无私地用自己的时间给我们免费解答.
作者: Frank.Lin    时间: 2018-3-2 16:32
本帖最后由 Frank.Lin 于 2018-3-2 16:34 编辑

py3里面如下代码,求老师解惑:
  1. class Vehicle:
  2.     def __init__(self,speed):
  3.         self.speed=speed

  4.     def drive(self,distance):
  5.         print('nees %f hour(s)'%(distance/self.speed)
  6.    class Bike(Vehicle):
  7.               pass
  8.               
  9.     class Car(Vehicle):
  10.               def __init__(self,speed,fuel):
  11.               vehicle._init_(self,speed)
  12.               self.fuel=fuel

  13.               def drive(self,distance)
  14.               Vehicle.drive(self,distance)
  15.                   print('need %f fuels'%(distance*self.fuel)


  16. b=Bike(15.0)
  17. c=Car(80.0,0.012)
  18. b.drive(100.0)
  19. c.drive(100.0)
  20.                
复制代码
系统报错,invalid syntax,再class Bike(vehicle)那里。请教下老师及各位同学,到底是什么原因?
作者: crossin先生    时间: 2018-3-3 20:31
Frank.Lin 发表于 2018-3-2 16:32
py3里面如下代码,求老师解惑:系统报错,invalid syntax,再class Bike(vehicle)那里。请教下老师及各位 ...

缩进不对。
class Bike 不是 Vehicle 内部
作者: xkk1212    时间: 2018-4-6 20:11
class A:
    def __init__(self,a,b):
        self.a=int(a)
        self.b=int(b)
    def add(self):
        print self.a+self.b


class B(A):
    A.__init__(self,a,b)
    def sub(self):
        print self.a-self.b
count= B('4',5)
count.add()

继承那部分我自己写了个例子想试试,意图是 B继承A的add方法,同时也新建一个方法,然后在B类里调A的add方法, 参数a,b是一样的从A里继承过来  可是我这样会报错Traceback (most recent call last):
  File "C:/Python27/5.py", line 9, in <module>
    class B(A):
  File "C:/Python27/5.py", line 10, in B
    A.__init__(self,a,b)
NameError: name 'self' is not defined
>>>

求解什么问题?
作者: crossin先生    时间: 2018-4-7 13:22
xkk1212 发表于 2018-4-6 20:11
class A:
    def __init__(self,a,b):
        self.a=int(a)

__init__ 不是手动调用的。就算调用,也不用加self。
看看课程里的例子
作者: xkk1212    时间: 2018-4-7 16:24
crossin先生 发表于 2018-4-7 13:22
__init__ 不是手动调用的。就算调用,也不用加self。
看看课程里的例子

好像有点明白了,我把顺序换了一下就可以了 但是我不太确定是不是我想的那种意思  谢谢老师了!
class A(object):
    def __init__(self,a,b):
        self.a=int(a)
        self.b=int(b)
    def add(self):
        print self.a+self.b


class B(A):
    def sub(a,b):
        A.__init__(self,a,b)   
        print self.a-self.b
count= B('4',5)
count.add()

作者: 小小艳紫    时间: 2018-4-20 11:30
xkk1212 发表于 2018-4-7 16:24
好像有点明白了,我把顺序换了一下就可以了 但是我不太确定是不是我想的那种意思  谢谢老师了!
class A ...

class A():
    def __init__(self,a,b):
        self.a = int(a)
        self.b = int(b)

    def add(self):
        print self.a+self.b

class B(A):
    def sub(self):
        print self.a-self.b

a = A(1,2)
a.add()
b = B(9,1)
b.sub()

B类完全继承了A类的init方法没有新的变量,是不是就不用再重新定义init了
作者: 小小艳紫    时间: 2018-4-20 14:17
找到了几个练习的小程序,链接:https://blog.csdn.net/bullpride/article/details/52022701
作者: huangdog    时间: 2018-4-30 19:57
本帖最后由 huangdog 于 2018-4-30 20:00 编辑

感觉
类和实例化的关系

就像类是盐,实例化是碗,把盐放到不同的碗里,不同的碗做不同的事情

是这样吗?

=================
还有__init__  是不是参数池,将要用到的参数先在__init__定义?
作者: crossin先生    时间: 2018-5-1 15:56
huangdog 发表于 2018-4-30 19:57
感觉
类和实例化的关系

差不多,我更喜欢用模具和做出来的东西打比喻

不是参数池,是初始化时候调用的函数。即使不在这里,在别的地方一样可以定义,只是这里更适合
作者: marvinmi    时间: 2018-10-16 20:27
这是我跑的代码,大概明白是什么意思,不过为什么说 Bike 这个类没有 drive 对象呢,这里好像是没有成功调用基类的方法吧

屏幕快照 2018-10-16 下午8.24.48.png (197.78 KB, 下载次数: 297)

代码

代码


作者: marvinmi    时间: 2018-10-16 20:34
marvinmi 发表于 2018-10-16 20:27
这是我跑的代码,大概明白是什么意思,不过为什么说 Bike 这个类没有 drive 对象呢,这里好像是没有成功调 ...

报错提示

屏幕快照 2018-10-16 下午8.28.25.png (12.68 KB, 下载次数: 289)

报错描述

报错描述


作者: marvinmi    时间: 2018-10-17 15:31
marvinmi 发表于 2018-10-16 20:34
报错提示

抱歉,低级错误,已经解决了,谢谢crossin老师
作者: amengguyi    时间: 2018-10-20 22:32
self.speed = speed 是什么意思?去初始化怎么理解呢
作者: crossin先生    时间: 2018-10-21 13:20
amengguyi 发表于 2018-10-20 22:32
self.speed = speed 是什么意思?去初始化怎么理解呢

speed是函数传进来的参数
self.speed 是成员变量

这两个不相干,只是正好名字一样,也可以取不同的名字
作者: 东东哥    时间: 2018-11-3 13:28
class Vehicle:
    def __init__(self,speed):
        self.speed=speed

    def drive(self,distance):
        print'need %f hour(s)'%(distance/slelf.speed)
class Bike(Vehicle):
    pass

class Car(Vehicle):
    def __int__(self,speed,fuel):
        Vehicle.__init__(self,speed)
        self.fuel=fuel

    def drive(self,distance):
        Vehicle.drive(self,distance)
        print'need %f fuels' % (distance*self.fuel)

b=Bike(15.0)
c=Car(80.0,0.012)
b.drive(100.0)
c.drive(100.0)
为什么会报错
Traceback (most recent call last):
  File "C:/Users/DONG/Desktop/PY/code/47(4).py", line 20, in <module>
    c=Car(80.0,0.012)
TypeError: __init__() takes exactly 2 arguments (3 given)
作者: crossin先生    时间: 2018-11-4 12:36
东东哥 发表于 2018-11-3 13:28
class Vehicle:
    def __init__(self,speed):
        self.speed=speed

__init__ ,不是 __int__
你拼错了,导致你定义的初始化没用起作用
作者: 万里江山    时间: 2019-4-21 16:03
感觉面向对象好难,我其实前后看了四节课得有十遍还是我太笨了
作者: crossin先生    时间: 2019-4-24 22:41
万里江山 发表于 2020-6-10 23:03
感觉面向对象好难,我其实前后看了四节课得有十遍还是我太笨了

可以暂时先不管,因为缺少场景去理解面向对象是比较难的。当你之后遇到适合场景才回头看,可能会有新感悟
作者: 杀杀杀    时间: 2020-7-27 15:58
是创建类的时候调用吗?是创建了这个类的实例时调用吧!
作者: crossin先生    时间: 2020-7-27 22:29
杀杀杀 发表于 2020-7-27 15:58
是创建类的时候调用吗?是创建了这个类的实例时调用吧!

你说得对,感谢指正!




欢迎光临 Crossin的编程教室 (https://bbs.crossincode.com/) Powered by Discuz! X2.5