美文网首页
Python中的面向对象以及类

Python中的面向对象以及类

作者: 莫辜负自己的一世韶光 | 来源:发表于2018-11-22 19:59 被阅读0次

    面向过程 VS 面向对象

    • 面向过程

    面向过程的程序设计思想是过程,也就是流程式编程思想.C语言就是面向过程的,它就像是精心设计好的一条流水线,已经事先考虑好了什么时候处理什么问题.
    优点: 简化了代码的复杂度,只要顺着程序的流程顺序书写即可.
    缺点: 不利于改变和维护,以及代码的重复利用.因为面向过程的编程,一旦一个环节需要修改,则整个程序就可能受到很大的影响.

    • 面向对象

    面向对象的核心思想是对象,把一切都当成对象来看待.把具有相似特征和功能的事物抽象为类,然后用类封装一些属性和方法.然后程序的完成,通过对象和对象之间的交互来完成.面向对象的编程思想我们主要考虑的是某个类应该具有什么属性,这个类可以提供什么样的功能.
    优点: 程序具有高度的扩展性.对于一个对象的单独修改,会反映到整个程序.并且把程序的创建更加的模块化了.

    Python得面向对象

    Python并不是完全的面向对象语言,它只是提供了支持.Python是同时支持函数式编程(面向过程)以及面向对象编程的语言.

    类 对象 实例 实例化

    • 类:

    具有相同特征的一类事物的高度抽象(如:人,狗,猫)

    • 实例/对象

    属于某类事物的具体的某个一个事物(如:小黑)

    • 实例化

    类 ==> 床架对象/实例 的过程就叫实例化.

    初识类和对象

    python中一切皆为对象,类型的本质就是类,所以,不管你信不信,你已经使用了很长时间的类了

    >>> dict #类型dict就是类dict
    <class 'dict'>
    >>> d=dict(name='eva') #实例化
    >>> d.pop('name') #向d发一条消息,执行d的方法pop
    'eva'
    

    在Python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是'类',对象则是这一类事物中的具体的一个

    类的相关知识

    类属性和实例属性

    属性就是属于一个对象的数据或者函数,我们可以通过句点(.)来访问属性,同时Python还支持在运作中添加和修改属性.
    类属性就是类对象所拥有的属性,它被所有的类对象的实例化对象所共有,在内存中只有一个副本.类似于C++/java中的静态成员变量.通过类名/或者实例对象名都可以访问.而实例属性,是某个类特有的属性,可以在init中声明创建,也可以在类的外部实例化一个类进行创建赋值.

    实例属性示例

    # encoding:utf-8
    __author__ = 'Fioman'
    __date__ = '2018/11/21 15:59'
    
    # 类属性
    class People:
        name = "Tom" # 公有的类属性
        __age = 18 # 私有的类属性
    
    p = People()
    print(p.name) # 实例对象调用
    print(People.name) # 类对象调用
    
    # print(People.__age)
    # print(p.__age)  不能在类外部访问私有的类属性.
    

    类属性示例

    # encoding:utf-8
    __author__ = 'Fioman'
    __date__ = '2018/11/21 15:59'
    
    
    # 实例属性
    class People:
        name = 'tom' # 类属性
        def __init__(self):
            self.age = 18 # 实例属性
    
    p = People()
    p.sex = "男" # 外部添加实例属性
    
    print(p.name) # 类属性
    print(p.age)  # init方式创建的实例属性
    print(p.sex)  # 外部创建的实例属性
    
    print(People.name) # 类可以访问类属性
    print(People.age) # 出错,类不可访问实例属性
    

    Python中类的方法也叫动态属性

    类的两种作用: 类属性引用和实例化

    属性引用

    class Person(object):
        role = 'person' #类属性
        def walk(self): # 这里的方法也是类属性,可以通过Person直接调用.
            print('people is walking...')
    
    print(Person.role)  # 查看人的role属性
    print(Person.walk) #  引用人的走路方法,注意这里不是调用
    

    实例化:

    类名加括号就是实例化,会自动触发init函数的运行,可以用它来为每个实例定制自己的特征

    # 使用__init__()实例属性定制自己的特征
    class Person: # 定义一个人类
        role = 'person' # 人的角色属性都是人
        def __init__(self,name):
            self.name = name  # 每个角色都有自己的昵称
    
        def walk(self):
            print("Person {} is walking".format(self.name))
    
    
    print(Person.role)
    print(Person.walk)
    p = Person("小黄")
    p1 = Person("小红")
    
    p.walk()
    p1.walk()
    # Person 小黄 is walking
    # Person 小红 is walking
    

    类属性的补充

    问题? 我们定义的类的属性到底保存到哪里去了?

    dir(类名): 查出的是一个名字列表,包括该类的属性列表.
    类名.dict: 查出的是一个字典,key为属性名,value为属性值.

    特殊的类属性

    实例方法,类方法,静态方法的使用和区别

    实例方法

    定义: 第一个参数必须是实例对象,一般命名为'self',通过它来传递实例属性和方法(也可以传递类属性和方法)

    调用: 只能由实例对象或者在类内调用

    class Person: # 定义一个人类
        role = 'person' # 人的角色属性都是人
        def __init__(self,name):
            self.name = name  # 每个角色都有自己的昵称
    
        def walk(self): # 实例方法
            print("Person {} is walking".format(self.name))
    
    
    print(Person.role)
    print(Person.walk)
    p = Person("小黄")
    p1 = Person("小红")
    
    p.walk()
    p1.walk()
    # Person.walk()# 报错,实例方法只能通过实例对象调用
    # Person 小黄 is walking
    # Person 小红 is walking
    

    类方法

    定义: 使用装饰器@classmethod.第一个参数必须是当前类对象,一般用cls来表示,通过它来传递类的属性和方法(不能传递实例的属性和方法)

    调用: 实例对象和类都可以调用

    # 类方法
    class People:
        country = 'china'
    
        # 但是用实例可以调用,在用实例调用的时候,相当于是在用实例
        # 隶属的类在调用.
        @classmethod # 类方法,属于类,而不属于具体的实例.
        def getCountry(cls):  # 只能传递和操作类属性和方法
            return cls.country
    
    p = People()
    print(p.getCountry()) #实例对象调用类方法
    print(People.getCountry()) #类对象调用类方法
    

    静态方法
    定义:使用装饰器@staticmethod.参数随意,没有self和cls参数,但是方法体中不能使用类或者实例的属性和方法.它主要用来创建一个方法,和类以及实例没有任何的关联的.

    调用:实例对象和类都可以调用.它相当于是一个全局方法.

    静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护.

    譬如,我想定义一个关于时间操作的类,其中有一个获取当前时间的函数。

    import time
    
    __author__ = 'Fioman'
    __date__ = '2018/11/21 15:59'
    
    
    class TimeTest(object):
        def __init__(self, hour, minute, second):
            self.hour = hour
            self.minute = minute
            self.second = second
    
        @staticmethod
        def showTime():
            return time.strftime("%H:%M:%S", time.localtime())
    
    
    print(TimeTest.showTime())
    t = TimeTest(2, 10, 10)
    nowTime = t.showTime()
    
    print(nowTime)
    

    如上,使用了静态方法(函数),然而方法体中并没使用(也不能使用)类或实例的属性(或方法)。若要获得当前时间的字符串时,并不一定需要实例化对象,此时对于静态方法而言,所在类更像是一种名称空间。

    其实,我们也可以在类外面写一个同样的函数来做这些事,但是这样做就打乱了逻辑关系,也会导致以后代码维护困难

    Python的面向对象的三大特性

    封装

    隐藏对象的属性和实现细节,仅对外提供公共访问方式.
    好处:
    提高复用性和数据的安全性

    原则:

    1. 将不需要对外提供的内容隐藏起来
    1. 把属性都隐藏,提供公共的访问对其访问.

    私有变量和私有方法

    在Python中用双下划线开头的方式将属性隐藏起来(设置成私有的)

    # encoding:utf-8
    __author__ = 'Fioman'
    __date__ = '2018/11/21 19:47'
    
    # 其实这只是一种变形操作
    # 类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:
    
    class A:
        __N = 0 #类的数据属性就应该是共享的,但是语法上是可以把类的数量属性设置成为私有的
        # 如__N,会变形为_A__N
    
        def __init__(self):
            self.__X = 10  # 变形为self._A__X
    
        def __foo(self): # 会变形为_A__foo
            print('from A')
    
        def bar(self):
            self.__foo() # 只有在类内部才可以通过__foo的形式访问到
    
    # A._A__N是可以放到的,即这种操作并不是严格意义上的显示外部访问,仅仅只是一种语法意义上的变形
    

    这种变形的特点

    1.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。

    2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。

    3.在子类定义的__x不会覆盖在父类定义的_x,因为子类中变形成了:子类名_x,而父类中变形成了:父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

    需要注意的问题是:
    1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:类名_属性,然后就可以访问了,如a._A__N

    2.变形的过程只在类的内部生效,在定义后的赋值操作,不会变形

    相关文章

      网友评论

          本文标题:Python中的面向对象以及类

          本文链接:https://www.haomeiwen.com/subject/omrcqqtx.html