Python基础-面向对象基础

来源:互联网 发布:手机淘宝修改差评 编辑:程序博客网 时间:2024/05/19 08:23

了解面向对象之前的一些知识

编程范式

是一种典型的编程风格,是一种方法学
编程范式决定了程序员对程序执行的看法
OOP中,程序是一系列对象之间的相互作用
Python中支持多种编程范式:面向过程、面向对象,面向切面(装饰器部分)等

OOP思想

面向对象的基本哲学:世界由具有各自运动规律和内部状态的对象组成,对象之间的相互作用和通讯构成了世界
唯一性,世界上没有两片相同的叶子,同样的,也没有两个完全相同的对象
分类性:分类是对现实世界的抽象
三大特性,继承,多态和封装

类与实例

类 是一类实例的抽象,抽象的属性和操作
实例 是类的具体化

定义类

class Name:这种方式在python3和python2.3之前比较流行,但是在python2.4之后所有类都要继承自object 类。class Name(object): class Name(Parents):

一个例子:

1234567891011121314151617181920212223242526272829
#!/usr/bin/env Python#coding=utf-8class People(object):   #object是所有类的基类,它定义了一些基本的操作。继承了object的类称为新式类    def __init__(self,name,sex,age):  #__init__(self,...),初始化方法,self,对象自身        self.name = name   #将传进来的值定义给对象自身的数据        self.sex = sex        self.age = age    def say(self,words):  #一个普通的方法        print 'saying %s .....' % words    def walk(self):        print "walking....."tom = People('tom','man',17)   #实例化一个对象,self参数会自动传入tom.say('hello')   #调用tom的say方法tom.walk()print tom.age   #打印tom的实例变量age===============结果=============root@tonglele /code/Python/oop_base # python code1.py saying hello .....walking.....17

类的封装性

私有成员

以双下划线开始,但不以双下划线结束
Python中没有真正的私有成员,我们可以通过一些方法调用。

1234567891011121314151617181920212223242526272829
 #!/usr/bin/env python# coding=utf-8class People(object):    def __init__(self,name,age):        self.name = name        self.__age = age     #一个私有属性    def print_info(self):        print self.name        print self.__age    def __test(self):   #一个私有方法        print 'calling test.....'tom = People('tom',60)print tom.nameprint tom.__age==========运行结果========root@tonglele /code/Python/oop_base # python code2.pytomTraceback (most recent call last):  File "code2.py", line 20, in <module>      print tom.__age      AttributeError: 'People' object has no attribute '__age'    #报错。

123456789101112131415161718192021222324252627282930313233
 #!/usr/bin/env python# coding=utf-8class People(object):    def __init__(self,name,age):        self.name = name        self.__age = age    def print_info(self):        print self.name        print self.__age    def __test(self):        print 'calling test.....'tom = People('tom',60)#print tom.name#print tom.__agetom.print_info()tom.__test()===========运行结果=============1 root@tonglele /code/Python/oop_base # python code2.py                                                      :( tom 60 Traceback (most recent call last):   File "code2.py", line 23, in <module>       tom.__test()       AttributeError: 'People' object has no attribute '__test'

类变量

定义在实例方法之外的变量
所有实例共享类变量,但某一个实例对类变量的修改不会影响其他的实例和类本身
类变量可以直接访问

1234567891011121314151617181920212223242526272829303132333435363738394041
 #!/usr/bin/env python#coding=utf-8class People(object):    count = 0    def __init__(self,name,sex,age):        self.name = name        self.sex = sex        self.age = age    def print_info(self):        print self.name        print self.sex        print self.agetom = People('tom','man',19)marry = People('marry','women',18)print People.countprint tom.countprint marry.countPeople.count = 100tom.count = 99marry.count = 98print '============'print People.countprint tom.countprint marry.count==========结果===========root@tonglele /code/Python/oop_base # python code3.py000============1009998

类方法

使用@classmethod装饰器装饰,第一个参数代表类本身,
类方法可以直接调用,类方法里可以定义类变量。在类方法里不能调用与实例相关的东西,即不能使用self

1234567891011121314151617181920212223242526272829303132
 #!/usr/bin/env python#coding=utf-8class People(object):    def __init__(self,name,sex,age):        self.name = name        self.sex = sex        self.age = age    def print_info(self):        print self.name        print self.sex        print self.age    @classmethod    def test(cls):  #cls代表类本身        cls.count = 10  #定义一个类变量        print 'calling test.....'People.test()    #类方法可以直接调用print People.count   #打印类变量tom = People('tom','man',19)tom.test()  #用实例调用类方法==========运行结果========root@tonglele /code/Python/oop_base # python code3.pycalling test.....10calling test.....

静态方法

@staticmethod装饰器装饰,可以直接调用,没有像类方法那样限定第一个参数

1234567891011121314151617181920212223242526272829
#!/usr/bin/env python#coding=utf-8class People(object):    def __init__(self,name,sex,age):        self.name = name        self.sex = sex        self.age = age    def print_info(self):        print self.name        print self.sex        print self.age    @staticmethod    def test():        print 'calling static--test.....'People.test()  #直接调用静态方法tom = People('tom','man',19)tom.test()  #通过实例调用静态方法========结果==========root@tonglele /code/Python/oop_base # python code3.pycalling static--test.....calling static--test.....

属性

@property装饰器可以使被装饰的方法称为一个属性,类似与其他语言中的get方法
属性的setter方法
其他的具体解释见代码片

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
 #!/usr/bin/env pythonimport timeimport datetimeclass Dog(object):    def __init__(self,n):        self.n = n        self.__a = None    def test(self):        print 'calling test.....'    @property     #open_f方法被@property装饰器装饰了之后成为一个属性    def open_f(self):        return self.__a == None    @open_f.setter     #当open_f方法被装饰之后它自己也变成了一个另一个装饰器,用来装饰这个open_f方法之后此时的这个open_f就相当于其他语言的set方法    def open_f(self,value):        self.__a = valueclass Timef(object):    def __init__(self):        self.__time = datetime.datetime.now()    @property    def time(self):        return self.__time.strftime('%Y-%m-%d %H:%M:%S')    @time.setter    def time(self,value):        self.__time = datetime.datetime.strptime(value,'%Y-%m-%d %H:%M:%S')t = Dog(1212)print t.open_ft.open_f = 7878    #给该属性赋值,相当于调用了set方法print t.open_f     #调用该属性,相当于调用了get方法tt = Timef()print tt.timett.time = '2016-03-20 21:34:21'print tt.time#time例子:#默认以字符串的形式返回当前的时间,也可以以字符串的形式设置时间,整体来说是封装了私有属性__time。==========运行结果=============root@tonglele /code/Python/oop_base # python code4.pyTrueFalse2016-06-29 22:10:202016-03-20 21:34:21

另一个常用的运用:
在工作中,有些需求需要对IP地址进行处理,因为在计算机中IP都是以整数的形式做运算的,
但是展现出来的时候都是以字符串形式(点分十进制),便于人类查看,就可以用上述方法实现对IP操作的封装

魔术方法

魔术方法总是以双下划线开头,并以双下划线结尾的,这些方法都是由特殊用途的
下面简单介绍一些:

__init__

__init__初始化方法,对实例对象的一些数据进行初始化

12345678910111213141516
 #!/usr/bin/env python# coding=utf-8class People(object):    def __init__(self,name,age):   #初始化函数        self.name = name    #将类=实例对象的一些数据初始化。。        self.age = age        print "init....."tom = People('tom',19)  #实例化一个对象==========运行结果=====root@tonglele /code/Python/oop_base # python code5.py init.....

__new__,__del__

__new__方法,相当于C++中的构造函数,下一篇具体介绍
__del__相当于C++中的析构函数,当对象被回收时做一些清理工作

__eq__

__eq__方法相当于重载了一个==等于运算符

__gt__

__gt__方法相当于重载了一个>大于号运算符

__add__

__add__方法相当与重载了一个+

__str__

__str__方法,定义了我们使用str方法或直接print一个对象的时候的一个行为
__repr__类似与__str__,不过__repr__返回的是机器可读的字符串,__str__返回的是人类可读的

__hash__

__enter__和__exit__

只要一个类实现了这个两个方法就可以使用with 语法

1234567891011121314151617
 #!/usr/bin/env python#coding=utf-8class W(object):    def __init__(self):        self.fileName = open('/mnt/file','w')    def __enter__(self):        return self.fileName    def __exit__(self,*excinfo): #该方法接受一个可变参数,出现异常的时候将异常        self.fileName.close()    #传值给该参数,在该函数里根据异常可以做相应的处理with W() as f:    f.write("hello world")

以上魔术方法的一些应用

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
#!/usr/bin/env python#coding=utf-8class Man(object):    def __init__(self,name,sex,age):        self.name = name        self.sex = sex        self.age = age    def __eq__(self,other):        return self.age == other.age and self.sex == other.sex and self.age == other.age    def __gt__(self,other):        return self.age > other.age    def __ne__(self,other):        return self.age != other.age or self.name != other.name or self.sex != other.sex    def __add__(self,other):        return Man(self.name+other.name,self.sex+other.sex,self.age+other.age)    def __str__(self):        return 'name: %s sex: %s age: %s \n' % (self.name,self.sex,self.age)    def __del__(self):        print 'del......' #做一些清理工作man1 = Man('tom','man',19)man2 = Man('harry','man',17)print man1 == man2print man1 > man2print man1 != man2print man1print man1 + man2===========结果==========FalseTrueTruename: tom sex: man age: 19 name: tomharry sex: manman age: 36  del...... del...... del......

继承

子类与父类:子类是对父类的扩展,在父类的属性和方法的基础上做一些扩展

一个继承的例子

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
#!/usr/bin/env pythonclass Phone(object):    #父类    def __init__(self,size,color,mem):  #父类的初始化方法,父类拥有尺寸,颜色,内存三个数据        self.size = size        self.color = color        self.mem = mem    def call(self):    #父类的call方法        print 'calling.....'    def msg(self):   #父类的msg方法        print 'sending msg......'class Phones(Phone):    #Phones类,继承了Phone类    def __init__(self,size,color,mem,pix):   #重写了初始化方法,加入了pix数据        self.pix = pix   #将新加入的数据写入        super(Phones,self).__init__(size,color,mem)  #再调用父类的初始化方法    def install_app(self,app):   #在父类的方法基础上,增加了一个install_app方法        print 'installing %s ......' % appclass Huawei(Phone):    def weixin(self,msg):        if msg.find('jiangfan') == -1:            print 'can\'t send....'        else:            print 'sending.....'p = Phone('4,0','black','4M')p.call()iphone = Phones('4.7','white','4G','1080*699')iphone.install_app('dangdang')hua = Huawei('3.5','black','2G')hua.weixin('jiangfan')==============结果===============calling.....installing dangdang ......sending.....

多继承

我们大多数情况下只会使用单继承,但python也提供多继承class ClassName(c1,c2...)

1234567891011121314151617181920212223242526
 #!/usr/bin/env pythonclass A(object):    def __init__(self):        pass    def m(self):        print 'A  -- m....'class B(object):    def n(self):        print 'B -- n....'class C(A,B):    passc = C()c.m()c.n()===========运行结果========A  -- m....B -- n....

但是多继承中也会出现一些问题:

1234567891011121314151617181920212223
#!/usr/bin/env pythonclass A(object):    def __init__(self):        pass    def m(self):        print 'A  -- m....'class B(object):    def m(self):        print 'B -- m....'class C(A,B):    passc = C()c.m()=========结果===========A  -- m....   #当多个父类中拥有同一个名称的方法时,子类采用继承顺序靠前的那个

1234567891011121314151617181920212223242526272829
 #!/usr/bin/env pythonclass A(object):    def __init__(self):        pass    def m(self):        print 'A  -- m....'class B(A):   #B继承于A    def m(self):        print 'B -- m....'class C(A,B):    passc = C()c.m()=========结果===========Traceback (most recent call last):    #继承关系发生混淆  File "test5.py", line 16, in <module>      class C(A,B):TypeError: Error when calling the metaclass bases        Cannot create a consistent method resolutionorder (MRO) for bases A, B

MRO:一种算法,在python中存在多继承,当继承列表中有同名方法的时候,python就是根据这个MRO来选择子类该执行哪个方法的。

感谢阅读,欢迎指正。

0 0
原创粉丝点击