zoukankan      html  css  js  c++  java
  • 十六、python面向对象基础篇

    面向对象基础:
    在了解面向对象之前,先了解下变成范式:
    编程范式是一类典型的编程风格,是一种方法学
    编程范式决定了程序员对程序执行的看法
    oop中,程序是一系列对象的相互作用
    python支持多种编程范式,面向过程,面向对象,面向切面(装饰器部分)等
    --------------------------------------------------------------------
    --------------------------------------------------------------------
    --------------------------------------------------------------------
    OOP思想:
    面向对象的基本哲学,世界由具有各自运动规律和内部状态的对象组成,对象之间的相互作用和通讯构成了世界。
    唯一性,世界上没有两片相同的树叶,同样的没有两个相同的对象
    分类性,分类是对现实世界的抽象
    三大特性,继承,多态和封装
    老祖宗都是打鱼的,我也是打鱼的 ====》继承
    老祖宗用木头插,我用渔网捕鱼 ====》多态
    人家找我借100块钱,我从银行拿100块钱给它,被必要告诉它我银行里有多少钱 ======》封装
    --------------------------------------------------------------------
    --------------------------------------------------------------------
    --------------------------------------------------------------------
    组织数据的示例:
    假如有一个表示门的的数据
    门有两个属性,门牌号和打开/关闭的状态
    有两个操作符,打开和关闭
    --------------------------------------------------------------------
    基本组织方式:
    #定义两个门和它的门牌号和状态
    door1 = [1,'打开']
    door2 = [2,'关闭']
    #定义函数做打开门的操作
    def opened(door)
    door[1] = '打开'
    #定义函数做关闭门的操作
    def closed(door)
    door[1] = '关闭'
    #这个时候我调用closed函数对door1进行关闭的操作
    closed(door1)
    print (door1)
     
    --------------------------------------------------------------------
    面向对象组织方式(用类来组织):
    #使用class关键字声明一个门的类
    class Door(object):
    a = 100 #这里定义了一个类变量
    def __init__(self,num,status):
    self.num = num
    self.status = status
    def opend(self):
    self.status = '打开'
    def closed(self):
    self.status = '关闭'
    def __test(self): #这里我定义了一个私有方法
    print ('__test')
     
     
    door1 = Door(1,'打开')
    door2 = Door(2,'关闭')
    door3 = Door(3,'打开')
    door1.__test() #这样会报错,因为它是一个私有成员
    door1._Door.__test() #这样就可以了,所以说python中没有真正的私有成员,但是一般没有人会这么用(只是为了测试下这个功能而已)
     
    .......
    #现在我想把door3关上
    door3.closed()
    #现在我想把door2打开
    door2.opend()
     
     
    解析以上语句:
    类与实例:
    类是一类实例的抽象,抽象的属性和操作,就像上面的Door类
    实例是类的具体化,door1 = Door(1,'打开'),实例化door1就是一个具体的对象了
     
    为什么我的door3可以直接使用closed()?
    因为door3 = Door(3,'打开'),是从Door这个类里面实例出来的具体对象,所以类Door里面有的属性,door3就会有
    就好像你是一个人,人就一定会有,两条腿,两只眼睛等等,除非你不是人
     
    定义类:
    class Door(object):
    首字母要大写
    object代表继承哪个类,Python2.4之后所有类都要继承自object类,所以最好加上这个。
     
    构造方法:
    函数在类里面称为方法,以双下划线__init__开头结束的方法代表是特殊方法
    def __init__(self,num,status):
    self.num = num
    self.status = status
    定义一个方法,第一个参数都是self,表示实例本身,调用方法的时候是不需要传递self这个参数的,
    解释器会自动的将当前的实例传递给self。如door1 = Door(1,'打开'),我们看见我们并不需要传递
    self参数,因为self代表的就是door1这个实例本身。
    __init__就是python类中的构造方法,实例化类的时候就会调用构造方法door1 = Door(1,'打开')传递的参数就是构造方法所需要的参数。
     
    实例变量:
    def __init__(self,num,status):
    self.num = num
    self.status = status
    self.num就是一个实例变量(也可称为实例属性),实例变量一般都在构造方法中定义,但也可以在类的其他方法里面定义(但要尽可能在构造方法中定义实例变量)
    实例变量是一个依附于某一个具体的实例的,定义语法为self.argument.
     
    定义实例方法:
    def closed(self):
    self.status = '关闭'
    像这个就是一个实例方法,但是你可以动态的修改实例方法,比如:
    def test():
    print ('test')
     
    door1.test = test
    door1.test()
    就像这样我首先定义了一个函数test(),然后我再将这个函数赋值给door1.test,然后我在调用door1.test()就变成了实际执行test()这个函数是一样的效果,这个在c里面是会出问题的
     
     
     
    接下来,讲讲类的封装性
    私有成员:
    *以双下划线开始,不以双下划线结束
    *python中其实没有真正的私有成员
    私有变量:
    self.__status = status
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------
    类变量:
    *定义在实例方法之外的变量
    *所有实例共享类变量,但某一个实例对类变量的修改不会影响其他实例和类本身
    *类变量可以直接访问
     
     
     
    类方法:
    *使用@classmethod装饰器装饰的方法
    *第一个参数代表类本身(cls,一定要写,区别实例方法,实例方法的是self)
    *类方法可以直接调用
    *类方法里可以定义类变量
    @classmethod
    def test(cls):
    cls.b = 200 #cls.b就是一个类变量,cls代表类本身
    print "class test"
    Door.test() #这里是说类变量可以直接调用
    print (Door.b()) #这里直接可以打印出它的类变量
    door1.test() #很自然,实例也可以直接访问
     
     
     
    静态方法:
    *静态方法以@staticmethod装饰器装饰
    *静态方法也可以直接调用
    *静态方法没有设定第一个参数
    @staticmethod
    def sta():
    print "static method"
    Door.sta() #这里是说类变量可以直接调用
    door1.sta() #很自然,实例也可以直接访问
    类能够调用的方法,实例一定也能调用,因为类比实例高一个级别
    而实例能够调用的方法,类就不一定能够直接调用了
     
     
     
    属性:
    *属性以@property装饰器装饰
    *属性的setter方法
    *属性的适用场合
     
    定义一个属性,@property装饰器可以使被装饰的方法称为一个属性,就不再是一个方法了,类似于其他语言的get方法,如上面的opend方法
    @property
    def opened(self):
    return self.status == "打开"
    作用即是返回某个实例(door1)的状态是“打开”还是“关闭”,如果没有@property的话,就还需要写个if判断语句来,等同于:
    def opened(self):
    if self.status == "打开":
    return True
    else:
    return False
     
     
    当一个方法被@property装饰之后,它本身也成了一个装饰器
    @opened.setter
    def opened(self,value):
    if value:
    self.status = '打开'
    else:
    self.status = '关闭'
     
    door1.opend = True
    这里这个opend.setter代表我要设置一个条件,如果value为真,我就让它的状态属于“打开”,否则它的状态就为“关闭”,
    然后我通过实例的方法door1.opend = True传一个值(True)给value,这个方法很实用,必须掌握,因为这样我们就不用
    那么麻烦的还去做判断什么的,可以直接设置一个属性,我用的时候door1.opend = True就是“打开”的状态,door1.opend = False就是关闭的状态。
     
    这里你如果要用就要先@property将某个方法变成一个装饰器,再用@opened.setter来设置它的状态,@property相当于一个get方法,@opened.setter相当于一个set方法,你没有get,哪来set啊。
    这两个通常都是成套的,也就是你有get方法就会有set方法,要不然设置不成套。
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
    下边是一个简单的时间类,默认以字符串的形式返回当前的时间,也可以以字符串的形式设置时间,整体来说是封装了私有属性__time
    import datetime
    class T(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 = T()
    print (t.time)
    t.time = '2016-12-20 15:30:00'
    print (t.time)
     
    执行之后返回值如下:
    >>>
    2016-04-29 16:41:04
    2016-12-20 15:30:00
     
    在工作中,有些需求需要对IP地址进行处理,因为在计算机中IP都是整数的形式做运算的,但是展现出来的时候都是字符串形式(点分十进制),便于人类查看,就可以使用上述方法实现对IP操作的封装。
     
     
     
  • 相关阅读:
    bzoj 4606: [Apio2008]DNA【dp】
    UOJ #206. 【APIO2016】Gap【交互题】
    bzoj 4071: [Apio2015]巴邻旁之桥【splay】
    bzoj 4069: [Apio2015]巴厘岛的雕塑【dp】
    bzoj 4070: [Apio2015]雅加达的摩天楼【spfa】
    洛谷 P3625 [APIO2009]采油区域【枚举】
    bzoj 1178: [Apio2009]CONVENTION会议中心(少见做法掉落!)【贪心+二分】
    bzoj 1179: [Apio2009]Atm【tarjan+spfa】
    洛谷 P3621 [APIO2007]风铃【贪心】
    bzoj 4898: [Apio2017]商旅【Floyd+分数规划+二分】
  • 原文地址:https://www.cnblogs.com/steven9898/p/11329429.html
Copyright © 2011-2022 走看看