13.面向对象编程

1、前言

前面一直是语法与面向过程编程,这张我们来学oop

2、直接开搞,python中如何创建一个类?

答: 用到关键字 class, 类名是MyFirst 括号的是 扩展的基类object

class MyFirst(object):
    'my first class' #类也有文档字符串哦
    foo = 100

3、静态变量(名字翻译好多:静态属性、类变量、静态数据)

class MyFirst(object):
    'my first class' #类也有文档字符串哦
    foo = 100

print(MyFirst.foo)

foo就是个静态变量………………

概念:它是属于类的,与类的实例对象无关,调用的时候用  类名.静态变量

4、方法

在类中的定义的函数,准确的说在python中叫方法(又称实例方法、对象方法)

class MyFirst(object):
    'my first class' #类也有文档字符串哦
    foo = 100

    def myNoActionMethod(self):  #self代表当前的类的实例对象,好吧,注意与普通函数的语法区别
        pass

5、怎么调用方法呢?

first = MyFirst()   #这里是得到MyFirst的一个实例对象 ,将引用赋值给变量first
first.myNoActionMethod()

当然首先要得到实例对象,然后  通过 . 调用方法

class MyFirst(object):
    'my first class' #类也有文档字符串哦
    foo = 100

    def myNoActionMethod(self):
        print("我是一个方法")

first = MyFirst()
first.myNoActionMethod()

输出结果:

>>>
我是一个方法

6、类特殊的静态变量

C.__name__ 类C的名字(字符串)

C.__doc__ 类C的文档字符串

C.__bases__ 类C的所有父类构成的元组

C.__dict__ 类C的属性

C.__module__ 类C定义所在的模块(1.5 版本新增)

C.__class__ 实例C对应的类(仅新式类中)

7、初始化一个类的实例对象

前面我们已经进行过初始化了,这里再总结下:

first = MyFirst() #在python中就是这么简单………… java中得用new哦

8、__init__(), 构造方法(还有其它名字:构造器,初始器,中文博大精深)

当类被调用时,咱们就去搞实例对象,python会检查是否实现了__init__()方法。

默认情况:如果没有定义或者叫做覆盖(重写)构造方法 __init__(),那就使用默认的,也就是说一个类肯定是有__init()__,没有重写,不代表没有,只是使用默认的。

重写情况:如果你重写了__init()__构造方法,那你创建一个实例对象的时候,就会调用你写的__init()__。

9、__new__(),又一个特殊的方法,先不说了,先知道有它就行

10、__del__(),该方法用于释放实例对象占用的内存,好吧,强行把实例对象占用的内存释放掉………………也是先知道即可…………

11、来个例子吧,包含__init__(), __new__()、__del__()………………叫停吧,书上的例子…慢慢深入

12、又谈到了如果计算一个类创建多少个实例对象,好家伙……用静态变量记录

上栗子:

class Person(object):
    count = 0

    def __init__(self): #构造方法
        Person.count = Person.count + 1

    def __del__(self):  #显示释放一个实例对象的方法
        Person.count -= 1

    def howManyObject(self):
        return Person.count

one = Person()
print(one.howManyObject())

例子重写两个特殊方法,用了一个类变量存储创建实例对象的数量

13、实例变量(又称:实例属性、对象变量)我的妈啊,被翻译就能折腾死是吧,呵呵

上例子:

class HotelRoom(object):
    'Hotel room rate calculator'

    def __init__(self, rt, sales = 0.085, rm = 0.1):   #构造方法,第一个self代表当前实例对象,这个不用传入,一个必选参数rt,两个默认值参数sales与rm
        '''HotelRoom default arguments:
        sales tax == 8.5% and room tax == 10%'''   #首行的文档字符串
        self.salesTax = sales  #实例变量salesTax
        self.roomTax = rm      #实例变量roomTax
        self.roomRate = rt     #实例变量roomRate

    def calcTotal(self, days = 1): #一个实例方法,第一个参数self,代表当前实例对象,第二个是默认值参数days
        'Calculate total: default to daily rate'
        daily = round((self.roomRate * (1 + self.roomTax + self.salesTax)), 2) #这里还调用了实例变量roomRate、roomTax、salesTax
        return float(days) * daily

sfo = HotelRoom(29)   #得到一个HotelRoom实例对象,将调用__init__()方法,因为构造方法有个必选参数,所以我们必须传入一个参数,这里传入参数为29
print(sfo.calcTotal(10)) #调用实例方法calcTotal,然后再调用print()函数

14、强调了__init__()不可返回其他对象

class Dog(object):

    def __init__(self):
        return 1

myDog = Dog()

输出结果:

Traceback (most recent call last):
  File "D:/temp/Dog.py", line 11, in <module>
    myDog = Dog()
TypeError: __init__() should return None, not 'int'
>>> 

因为构造器只能返回实例对象,返回不是None的实例对象都会抛出异常TypeError,也就是说不要用return

15、又一次强调 dir()函数可以返回所有的类变量(返回的集合是List)、 __dirt__可以看到所有的实例变量(返回的集合是字典)

16、类变量(静态变量)再谈……

例子:

class Dog(object):
    eat = 'meat'

    def __init__(self):
        pass

myDog = Dog()
print(Dog.eat)    #通过类名
print(myDog.eat)  #通过实例对象的引用

类变量:可以通过类名访问、也可以用实例对象访问( 这里与java是一致哦)

不建议通过实例对象去访问类变量(java里也一样不建议这么做,你只需要知道即可)

17、self小结

self是什么?

答:任何一个实例方法定义中的第一个参数都是变量self,它表示调用此实例方法的实例对象

18、插一句啊,如果你的类没有继承任何类,那么默认继承的是object,所以你可以省略(ojbect),下面这俩是一样的…………

class Dog:
    eat = 'meat'

    def __init__(self):
        pass
class Dog(object):
    eat = 'meat'

    def __init__(self):
        pass

19、哈哈,终于到静态方法(又称类方法),等的哥哥花都快谢了…………

静态方法:类中的函数,属于类,不需要实例对象哦,就可以使用哦,亲爱的……

旧版本的python是这么创建静态方法的,看例子:

class TestStatic:

    def foo():
        print("foo()")

    foo = staticmethod(foo) #利用staticmethod函数将foo函数变为静态方法,然后把函数引用赋值给foo
TestStatic.foo() # 利用类直接调用,算是正统

my = TestStatic()

my.foo() #当然实例对象也可以调用静态方法,同样我们不推荐这样使用,你只需知道这种方式可以即可

另外一种方式,看例子:

class TestStatic2:

    def foo(cls):
        print("I am the best")

    foo = classmethod(foo) #利用classmethod函数将foo函数变为类方法,嘿嘿

20、python2.4以后静态方法的创建,我们当然直接用高大上的函数修饰符(又称作函数装饰器………………中文博大精深,翻译一会一个名字对于新人来说,越搞越混乱)

上栗子:

例子A

class TestStatic2:

    @staticmethod #高大上的函数修饰符,又叫装饰器
    def foo():
        print("I am the best")

例子B

class TestStatic2:

    @classmethod #用这个函数修饰符,也可,不过要注意有cls参数
    def foo(cls): #<span style="color:#ff0000;">注意这里的cls参数</span>
        print("I am the best")

21、组合……代码复用的精髓,这个要慢慢体会的哦,亲

这里的类与类之间的关系,称为 has a…………

22、派生(又称继承),也是代码复用的精髓,也要慢慢体会哦,亲

这里的关系称作:is a………………

23、来吧,python怎么创建子类呀?怎么玩继承啊?

答:python支持多继承

class Man(Person, Thinking): #类Man, 继承自Person、Thinking
    pass

24、来个继承经典例子,这里不懂,就代表你还不明白面向对象

class Parent(object):    #定义一个Parent类   扩展自object

    def printParent(self):
        print ('they are parents')

class Child(Parent):        #定义Child类扩展自Parent

    def printChild(self):
        print("hello child")

par = Parent()  #先来个Parent实例对象
par.printParent()  #调用Parent的实例方法

chi = Child()   #再来个Child实例对象
chi.printChild() #调用Child实例方法

chi2 = Child() #再整个Child实例对象
chi2.printParent()  #调用Parent的实例方法  

25、好吧,直接上重写吧(overriding)

class Father(object):

    def eat(self):
        print("老爹吃肉")

class Son(Father):

    def eat(self):   #俺们把从Father那里得到eat方法,又重写了,所以输出结果必然是……往下看
        print("儿子吃素")

s = Son()
s.eat()

输出结果:

>>>
儿子吃素

疑问1:那我还想调用父类的eat方法呢?怎么办呢?

s = Son()
s.eat() #这里调用的eat方法

Father.eat(s)  #这里调用了父类的eat方法 不推荐这么用啊

疑问2:我想在子类重写的方法里直接调用父类的原方法呢?

建议用super

class Father(object):

    def eat(self):
        print("老爹吃肉")

class Son(Father):

    def eat(self):
        super(Son, self).eat() #利用super函数可以办到 哈哈
        print("儿子吃素")

也可以这样(不建议使用这个):

class Father(object):

    def eat(self):
        print("老爹吃肉")

class Son(Father):

    def eat(self):
        Father.eat(self)
        print("儿子吃素")

26、继承体系下的__init__()方法,python中,不会硬性要求你必须调用父类的构造器,如果你没有调用,python可不会帮你调用哦。 这里和java可不一样

class Father(object):

    def walk(self):
        print("new Father().walk(self)")

    def __init__(self):
        print("老子构造方法")

class Son(Father):

    def __init__(self):
        print("儿子构造方法")

s = Son()

输出结果:

>>>
儿子构造方法

因为python坑爹的就是不会要求你调用父类的构造器,你如果想的话

显式的调用父类的构造器:

class Father(object):

    def walk(self):
        print("new Father().walk(self)")

    def __init__(self):
        print("老子构造方法")

class Son(Father):

    def __init__(self):
        super(Son, self).__init__() #这里利用super函数,显示的调用父类的构造器,好吧,赞赞啊
        print("儿子构造方法")

s = Son()

27、python从2.2版本开始支持从 基本数据类型扩展子类、即 float int等等,先给老子知道这里就可以。

28、又谈到了多重继承,python啊python,你咋这牛逼呢?慢慢深入吧,一时半会不可能的………………

29、内建函数…………介绍…………一堆,慢慢深入

issubclass() 布尔函数判断一个类是另一个类的子类或子孙类。它有如下语法:

issubclass(sub, sup)

isinstance() 布尔函数在判定一个对象是否是另一个给定类的实例时,非常有用。它有如下

语法:

isinstance(obj1, obj2)

30、后面还有好多高级特性吧、什么 访问控制的 __ 、 _,哈哈,没事我会战胜苦难的,还有元类……还有…………总之类这里绝对没有那么简单,本章我们告一段落……………………………………………………………………加油…………………………深入…………………………

很喜欢这个函数……

def foo(data):
    if isinstance(data, int):
        print 'you entered an integer'
    elif isinstance(data, str):
        print 'you entered a string'
    else:
        raise TypeError, 'only integers or strings!' #raise用于抛出异常, 类似与java中的throw
时间: 2024-10-08 04:45:15

13.面向对象编程的相关文章

python核心编程--笔记

python核心编程--笔记 的解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找python路径 1.4 –v   冗余输出(导入语句详细追踪) 1.5 –m mod 将一个模块以脚本形式运行 1.6 –Q opt 除法选项(参阅文档) 1.7 –c cmd 运行以命令行字符串心事提交的python脚本 1.8 file   以给定的文件运行python脚本 2 _在解释器中表示最后

Python核心编程这本书的一些错误

<Python核心编程第二版>这本书比<Python基础教程第二版修订版>详细很多,丰富了很多细节,虽然它是一本经典的入门书,但我发现还是存在一些明显的错误.在面向对象编程这一章,有两个错误 1).它说任何类都有一些内置的特殊的类属性(即程序员不在类中定义也会存在),见截图 2).它说__new__方法比__init__方法更像是类的构造器.见截图: 下面进行测试: 1 #encoding:utf-8 2 class MyClass(): 3 def doPrint(self):

Python核心编程 第3版 中文版pdf

[下载地址] <Python核心编程(第3版)>是经典畅销图书<Python核心编程(第二版)>的全新升级版本,总共分为3部分.第1部分为讲解了Python的一些通用应用,包括正则表达式.网络编程.Internet客户端编程.多线程编程.GUI编程.数据库编程.Microsoft Office编程.扩展Python等内容.第2部分讲解了与Web开发相关的主题,包括Web客户端和服务器.CGI和WSGI相关的Web编程.Django Web框架.云计算.高级Web服务.第3部分则为一

《Python核心编程》 第五章 数字 - 课后习题

课后习题  5-1 整形. 讲讲 Python 普通整型和长整型的区别. 答:普通整型是绝大多数现代系统都能识别的. Python的长整型类型能表达的数值仅仅与你机器支持的(虚拟)内存大小有关. 5-2 运算符 (a) 写一个函数,计算并返回两个数的乘积 (b) 写一段代码调用这个函数,并显示它的结果 答: def pro(a,b): p = a*b return p a = int(raw_input("a=")) b = int(raw_input("b="))

Python核心编程(第二版) 第六章习题答案

6–1.字符串.string 模块中是否有一种字符串方法或者函数可以帮我鉴定一下一个字符串是否是另一个大字符串的一部分? 答:有,string.find(str,beg,end) 6–2.字符串标识符.修改例 6-1 的 idcheck.py 脚本,使之可以检测长度为一的标识符,并且可以识别 Python 关键字,对后一个要求,你可以使用 keyword 模块(特别是 keyword.kelist)来帮你. 1 #!/usr/bin/python 2 3 import string 4 impo

学习《Python核心编程》做一下知识点提要,方便复习(一)

学习<Python核心编程>做一下知识点提要,方便复习. 计算机语言的本质是什么? a-z.A-Z.符号.数字等等组合成符合语法的字符串.供编译器.解释器翻译. 字母组合后产生各种变化拿python来说就是.keyword.数值,类,函数,运算符,操作符...... 1.变量不用声明,类型不固定 2.True,False = False,True读出了什么?True是个bool()类实例 3.类型工厂函数就是python2.2后把int() bool()等对数据类型操作的函数分装成对象 类 了

Python核心编程(第二版) 第五章习题答案

5-1.整型.讲讲Python普通整型和长整型的区别. 答:Python 的标准整数类型是最通用的数字类型.在大多数 32 位机器上,标准整数类型的取值范围是-2**31到 2**31-1,也就是-2,147,483,648 到 2,147,483,647.如果在 64 位机器上使用 64 位编译器编译 Python,那么在这个系统上的整数将是 64 位. Python 的长整数类型能表达的数值仅仅与你的机器支持的(虚拟)内存大小有关. 5-2.操作符.(a)写一个函数,计算并返回两个数的乘积.

Python核心编程第五章习题

Python核心编程-第五章-习题 5.1  整形,讲讲Python普通整形与长整形的区别? Python的标准整形类型是最通用的数字类型.在大多数32位机器上,标准整形类型的取值范围是-2**32-2**32 - 1. Python的长整型类型能表达的数值仅仅与你的机器支持的(虚拟)内存大小有关,换句话说,Python能轻松表达很大的整数. 长整型类型是标准整形类型的超集,当程序需要使用比标准整形更大的整型时,可以使用长整型类型,在整型值后面添加L,表示这个为长整型,3.0版本已经统一称为为整

python核心编程--第八章 8.15 练习

#!/usr/bin/python # -*- coding: utf-8 -*- # 8–2. 循环. 编写一个程序, 让用户输入三个数字: (f)rom, (t)o, 和 (i)ncrement . # 以 i为步长, 从 f 计数到 t , 包括 f 和 t . 例如, 如果输入的是 f == 2, # t == 26, i == 4 , 程序将输出 2, 6, 10, 14, 18, 22, 26. f = int(raw_input("Please input from: "

Python核心编程(第二版) 第二章习题答案 未完待续

2-2.程序输出.阅读下面的Python脚本.#!/usr/bin/env python1 + 2 * 4(a)你认为这段脚本是用来做什么的?(b)你认为这段脚本会输出什么?(c)输入以上代码,并保存为脚本,然后运行它,它所做的与你的预期一样吗?为什么一样/不一样?(d)这段代码单独执行和在交互解释器中执行有何不同?试一下,然后写出结果.(e)如何改进这个脚本,以便它能和你想象的一样工作?答:(a)这段脚本是用来计算表达式的值(b)脚本会输出9(c)保存为脚本,运行后没有输出.和自己预期不一样.