python之面向对象编程浅谈

1.python中的类与对象

 1 Python中定义类的方式比较简单:
 2
 3 class 类名:
 4
 5 类变量
 6
 7 def __init__(self,paramers):
 8
 9 def 函数(self,...)
10
11 …...
12
13 其中直接定义在类体中的变量叫类变量,而在类的方法中定义的变量叫实例变量。类的属性包括成员变量和方法,其中方法的定义和普通函数的定义非常类似,但方法必须以self作为第一个参数。

举例:

 1 >>>class MyFirstTestClass:
 2
 3 class Spec="it is a test class"
 4
 5 def__init__(self,word):
 6
 7 print"say "+word
 8
 9 def hello(self,name):
10
11 print"hello "+name
12
13  

在Python类中定义的方法通常有三种:实例方法,类方法以及静态方法。这三者之间的区别是实例方法一般都以self作为第一个参数,必须和具体的对象实例进行绑定才能访问,而类方法以cls作为第一个参数,cls表示类本身,定义时使用@classmethod;而静态方法不需要默认的任何参数,跟一般的普通函数类似.定义的时候使用@staticmethod。

 1 >>>class MethodTest():
 2
 3 count= 0
 4
 5 defaddCount(self):
 6
 7 MethodTest.count+=1
 8
 9 print"I am an instance method,my count is"+str(MethodTest.count),self
10
11 @staticmethod
12
13 defstaticMethodAdd():
14
15 MethodTest.count+=1
16
17 print"I am a static methond,my count is"+str(MethodTest.count)
18
19 @classmethod
20
21 defclassMethodAdd(cls):
22
23 MethodTest.count+=1
24
25 print"I am a class method,my count is"+str(MethodTest.count),cls
26
27
28
29 >>>
30
31 >>>a=MethodTest()
32
33 >>>a.addCount()
34
35 Iam an instance method,my count is 1 <__main__.MethodTest instanceat 0x011EC990>
36
37 >>>MethodTest.addCount()
38
39
40
41 Traceback(most recent call last):
42
43 File"<pyshell#5>", line 1, in <module>
44
45 MethodTest.addCount()
46
47 TypeError:unbound method addCount() must be called with MethodTest instance asfirst argument (got nothing instead)
48
49 >>>a.staticMethodAdd()
50
51 Iam a static methond,my count is2
52
53 >>>MethodTest.staticMethodAdd()
54
55 Iam a static methond,my count is3
56
57 >>>a.classMethodAdd()
58
59 Iam a class method,my count is4 __main__.MethodTest
60
61 >>>MethodTest.classMethodAdd()
62
63 Iam a class method,my count is5 __main__.MethodTest

从上面的例子来看,静态方法和类方法基本上区别不大,特别是有Java编程基础的人会简单的认为静态方法和类方法就是一回事,可是在Python中事实是这样的吗?看下面的例子:

 1 >>>MethodTest.classMethodAdd()
 2
 3 Iam a class method,my count is5 __main__.MethodTest
 4
 5 >>>class subMethodTest(MethodTest):
 6
 7 pass
 8
 9 >>>b=subMethodTest()
10
11 >>>b.staticMethodAdd()
12
13 Iam a static methond,my count is6
14
15 >>>b.classMethodAdd()
16
17 Iam a class method,my count is7 __main__.subMethodTest
18
19 >>>a.classMethodAdd()
20
21 Iam a class method,my count is8 __main__.MethodTest
22
23 >>>

如果父类中定义有静态方法a(),在子类中没有覆盖该方法的话,Sub.a()仍然指的是父类的a()方法。而如果a()是类方法的情况下,Sub.a()指向的是子类。@staticmethod只适用于不想定义全局函数的情况。

2.python的封装

面向对象程序设计中的术语对象(Object)基本上可以看做数据(特性)以及由一系列可以存取、操作这些数据的方法所组成的集合。传统意义上的“程序=数据结构+算法”被封装”掩盖“并简化为“程序=对象+消息”。对象是类的实例,类的抽象则需要经过封装。封装可以让调用者不用关心对象是如何构建的而直接进行使用。

一个简单的Python类封装如下:

 1 _metaclass_=type # 确定使用新式类
 2 class Animal:
 3
 4     def __init__(self): #构造方法 一个对象创建后会立即调用此方法
 5         self.Name="Doraemon"
 6         print self.Name
 7
 8     def accessibleMethod(self): #绑定方法 对外公开
 9         print "I have a self! current name is:"
10         print self.Name
11         print "the secret message is:"
12         self.__inaccessible()
13
14     def __inaccessible(self): #私有方法 对外不公开 以双下划线开头
15         print "U cannot see me..."
16
17     @staticmethod
18     def staticMethod():
19         #self.accessibleMethod() #在静态方法中无法直接调用实例方法 直接抛出异常
20         print "this is a static method"
21
22     def setName(self,name): #访问器函数
23         self.Name=name
24
25     def getName(self): #访问器函数
26         return self.Name
27
28     name=property(getName,setName) #属性 可读可写

构造函数和析构函数

Python的构造函数有两种,__init__和__new__,__init__的调用不会返回任何值,在继承关系中,为了保证父类实例正确的初始化,最好显示的调用父类的__init__方法。与__init__不同,__new__实际是个类方法,以cls作为第一个参数。

如果类中同时定义了__init__和__new__方法,则在创建对象的时候会优先使用__new__.

class A(object):

def __init__(self):

print("in init")

def __new__(self):

print("in new")

A()

如果__new__需要返回对象,则会默认调用__init__方法。利用new创建一个类的对象的最常用的方法为:super(currentclass,cls).__new__(cls[, ...])

class A(object):

def __new__(cls):

Object = super(A,cls).__new__(cls)

print "in New"

return Object

def __init__(self):

print "in init"

class B(A):

def __init__(self):

print "in B‘s init"

B()

__new__构造函数会可变类的定制的时候非常有用,后面的小节中会体现。

Python由于具有垃圾回收机制,通常不需要用户显示的去调用析构函数,即使调用,实例也不会立即释放,而是到该实例对象所有的引用都被清除掉后才会执行。

>>>class P:

def__del__(self):

print"deleted"

>>>class S(P):

def__init__(self):

print‘initialized‘

def__del__(self):

P.__del__(self)

print"child deleted"

>>>a=S()

initialized

>>>b=a

>>>c=a

>>>id(a),id(b),id(c)

(18765704,18765704, 18765704)

>>>del a

>>>del b

>>>del c

deleted

childdeleted

>>>

3. Python中的继承

Python同时支持单继承与多继承,继承的基本语法为class新类名(父类1,父类2,..),当只有一个父类时为单继承,当存在多个父类时为多继承。子类会继承父类的所有的属性和方法,子类也可以覆盖父类同名的变量和方法。在传统类中,如果子类和父类中同名的方法或者属性,在查找的时候基本遵循自左到右,深度优先的原则。如下列:

 1 >>>class A:
 2
 3 defsayhi(self):
 4
 5 print‘I am A hi‘
 6
 7 >>>class B:
 8
 9 defsayhi(self):
10
11 print‘I am B Hi‘
12
13
14
15 >>>class C(A,B):
16
17 pass
18
19 >>>d=C()
20
21 >>>d.sayhi()
22
23 Iam A hi
24
25 >>>B.sayhi(d)
26
27 Iam B Hi

单继承

 1 _metaclass_=type # 确定使用新式类
 2 class Animal:
 3
 4     def __init__(self):
 5         self.Name="Animal"
 6
 7     def move(self,meters):
 8         print "%s moved %sm." %(self.Name,meters)
 9
10 class Cat(Animal): #Cat是Animal的子类
11
12      def __init__(self):  #重写超类的构造方法
13         self.Name="Garfield"
14
15 ##     def move(self,meters): #重写超类的绑定方法
16 ##        print "Garfield never moves more than 1m."
17
18 class RobotCat(Animal):
19
20     def __init__(self):  #重写超类的构造方法
21         self.Name="Doraemon"
22
23 ##     def move(self,meters): #重写超类的绑定方法
24 ##        print "Doraemon is flying."
25
26 obj=Animal()
27 obj.move(10) #输出:Animal moved 10m.
28
29 cat=Cat()
30 cat.move(1) #输出:Garfield moved 1m.
31
32 robot=RobotCat()
33 robot.move(1000) #输出:Doraemon moved 1000m.

多重继承

 1 class Animal:
 2
 3     def eat(self,food):
 4         print "eat %s" %food
 5
 6 class Robot:
 7
 8     def fly(self,kilometers):
 9         print "flyed %skm." %kilometers
10
11 class RobotCat(Animal,Robot): #继承自多个超类
12
13     def __init__(self):
14         self.Name="Doraemon"
15
16 robot=RobotCat() # 一只可以吃东西的会飞行的叫哆啦A梦的机器猫
17 print robot.Name
18
19 robot.eat("cookies") #从动物继承而来的eat
20
21 robot.fly(10000000) #从机器继承而来的fly

需要注意的地方,即如果一个方法从多个超类继承,那么务必要小心继承的超类(或者基类)的顺序:

 1 class Animal:
 2
 3     def eat(self,food):
 4         print "eat %s" %food
 5
 6     def move(self,kilometers): #动物的move方法
 7         pass
 8
 9 class Robot:
10
11     def move(self,kilometers): #机器的move方法
12         print "flyed %skm." %kilometers
13
14 class RobotCat(Animal,Robot): #继承自多个超类 如方法名称相同,注意继承的顺序
15 #class RobotCat(Robot,Animal):
16     def __init__(self):
17         self.Name="Doraemon"
18
19 robot=RobotCat() # 一只可以吃东西的会飞行的叫哆啦A梦的机器猫
20 print robot.Name
21
22 robot.eat("cookies") #从动物继承而来的eat
23
24 robot.move(10000000) #本来是要从机器继承move方法,但是因为继承的顺序,这个方法直接继承自动物而pass掉

关于继承的构造函数:

1.如果子类没有定义自己的构造函数,父类的构造函数会被默认调用,但是此时如果要实例化子类的对象,则只能传入父类的构造函数对应的参数,否则会出错

classAddrBookEntry(object):

‘addressbook entry class‘

def__init__(self, nm, ph):

self.name= nm

self.phone= ph

print‘Created instance for:‘, self.name

defupdatePhone(self, newph):

self.phone = newph

print‘Updated phone# for:‘, self.name

classEmplAddrBookEntry(AddrBookEntry):

‘EmployeeAddress Book Entry class‘

defupdateEmail(self, newem):

self.email= newem

print‘Updated e-mail address for:‘, self.name

john= EmplAddrBookEntry(‘John Doe‘, ‘408-555-1212‘)

printjohn.name

 2.如果子类定义了自己的构造函数,而没有显示调用父类的构造函数,则父类的属性不会被初始化

classAddrBookEntry(object):

‘addressbook entry class‘

def__init__(self, nm, ph):

self.name= nm

self.phone= ph

print‘Created instance for:‘, self.name

defupdatePhone(self, newph):

self.phone = newph

print‘Updated phone# for:‘, self.name

classEmplAddrBookEntry(AddrBookEntry):

‘EmployeeAddress Book Entry class‘

def__init__(self, nm, ph, id, em):

#AddrBookEntry.__init__(self, nm,ph)

self.empid= id

self.email= em

defupdateEmail(self, newem):

self.email= newem

print‘Updated e-mail address for:‘, self.name

john= EmplAddrBookEntry(‘John Doe‘, ‘408-555-1212‘,42, ‘[email protected]‘)

printjohn.email

printjohn.empid

输出:

[email protected]

42

Traceback(most recent call last):

printjohn.name

AttributeError:‘EmplAddrBookEntry‘ object has no attribute ‘name‘

3.如果子类定义了自己的构造函数,显示调用父类,子类和父类的属性都会被初始化

classAddrBookEntry(object):

‘addressbook entry class‘

def__init__(self, nm, ph):

self.name= nm

self.phone= ph

print‘Created instance for:‘, self.name

defupdatePhone(self, newph):

self.phone = newph

print‘Updated phone# for:‘, self.name

classEmplAddrBookEntry(AddrBookEntry):

‘EmployeeAddress Book Entry class‘

def__init__(self, nm, ph, id, em):

AddrBookEntry.__init__(self, nm,ph)

self.empid= id

self.email= em

defupdateEmail(self, newem):

self.email= newem

print‘Updated e-mail address for:‘, self.name

john= EmplAddrBookEntry(‘John Doe‘, ‘408-555-1212‘,42, ‘[email protected]‘)

printjohn.email

printjohn.empid

printjohn.name

4.python的多态

 1 class calculator:
 2     def count(self, args):
 3         return 1
 4
 5
 6 calc = calculator()  # 自定义类型
 7
 8 from random import choice
 9
10 obj = choice([‘hello,world‘, [1, 2, 3], calc])  # obj是随机返回的 类型不确定
11 print (type(obj))
12 print(obj.count(‘a‘))# 方法多态

对于一个临时对象obj,它通过Python的随机函数取出来,不知道具体类型(是字符串、元组还是自定义类型),都可以调用count方法进行计算,至于count由谁(哪种类型)去做怎么去实现我们并不关心。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 class Duck:
 4     def quack(self):
 5         print("Quaaaaaack!")
 6
 7     def feathers(self):
 8         print("The duck has white and gray feathers.")
 9
10
11 class Person:
12     def quack(self):
13         print("The person imitates a duck.")
14
15     def feathers(self):
16         print("The person takes a feather from the ground and shows it.")
17
18
19 def in_the_forest(duck):
20     duck.quack()
21     duck.feathers()
22
23
24 def game():
25     donald = Duck()
26     john = Person()
27     in_the_forest(donald)
28     in_the_forest(john)
29
30
31 game()

就in_the_forest函数而言,参数对象是一个鸭子类型和person类型,它实现了两个类型的相同名称的方法,打印的内容不一样,只是因为

下面是运算符号(方法)的多态

1 def add(x,y):
2     return x+y
3
4 print add(1,2) #输出3
5
6 print add("hello,","world") #输出hello,world
7
8 print add(1,"abc") #抛出异常 TypeError: unsupported operand type(s) for +: ‘int‘ and ‘str‘

时间: 2024-10-05 06:29:58

python之面向对象编程浅谈的相关文章

C++ Primer 学习笔记_73_面向对象编程 --再谈文本查询示例

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g

C++ Primer 学习笔记_73_面向对象编程 -再谈文本查询示范

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

Python 3面向对象编程

这篇是计算机类的优质预售推荐>>>><Python 3面向对象编程> 编辑推荐 本书不是Python 的入门书籍,适合具有Python 基础经验的开发人员阅读.如果你拥有其他面向对象语言的经验,你会更容易理解本书的内容. 内容简介 Python 是一种面向对象的解释型语言,面向对象是其非常重要的特性.本书通过Python 的数据结构.语法.设计模式,从简单到复杂,从初级到高级,一步步通过例子来展示了Python 中面向对象的概念和原则.本书不是Python 的入门书籍,

C++ Primer 学习笔记_74_面向对象编程 -再谈文本查询示范[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g

python的面向对象编程

面向对象编程是一种程序的范式,它把程序看成是对不同对象的相互调用,对现实世界建立的一种模型. 面向对象编程的基本思想,类和实例.类用于定义抽象对象,实例根据类的定义被创建出来. 在python当中我们使用下面的方法来定义类(按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的.): class Python(object): pass 我们实例化方法的话呢就使用: xaioming = Python() 在面向对象之后呢我们要进行属性的设置.

python 之面向对象编程

面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度. 而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象

Python基础----面向对象编程介绍、类和对象

面向对象变成介绍 面向过程编程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西.主要应用在一旦完成很少修改的地方,如linux内核.git.apache服务器等 优点:极大的降低了程序的设计复杂度 缺点:可扩展性差,改动一个地方很可能要改多个地方,牵一发而动全身 面向对象编程:不是编程的全部,只是用来解决软件可扩展性的 核心是对象(上帝式思维),对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.面向对象就是把计算

C++面向对象之浅谈

从今天起,我就开始学习c++了,终于要面向对象编程了(对象啊,希望真的可以有个对象).我准备把每天的学习心得写成博文,分享给大家,都是新手,言语表达什么方面不合适的地方,欢迎指正(你猜我会不会改) 首先,c++是一门面向对象的语言,他和面向过程的语言是本质上的区别. 面向过程的语言,采取的是自顶向下,全面的开发,在开发的过程中,一个人要负责绝大多数的内容,代码的重复利用率很低. 面向对象的语言,将的是万物皆对象,这门编程语言是从现实中抽象而来,在语言的设计上很大部分都是来源于我们身边的例子 .有