• python的面向对象编程


    面向对象编程是一种程序的范式,它把程序看成是对不同对象的相互调用,对现实世界建立的一种模型。

    面向对象编程的基本思想,类和实例。类用于定义抽象对象,实例根据类的定义被创建出来。

    在python当中我们使用下面的方法来定义类(按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的。):

    class Python(object):
            pass

    我们实例化方法的话呢就使用:

    xaioming = Python()

    在面向对象之后呢我们要进行属性的设置。

    class Person:
        def _init__(self,name):
    self.name = name
    p1 = Person() p1.name = 'Bart' p2 = Person() p2.name = 'Adam' p3 = Person() p3.name = 'Lisa' L1 = [p1, p2, p3] L2 = sorted(L1, key=lambda x:x.name) print L2[0].name print L2[1].name print L2[2].name

    结果是:

    Adam
    Bart
    Lisa

    并且属性也可以像变量一样进行加减。

    在C++和java中都拥有面向对象编程,同时他们都具有构造函数这个东西,在Python当中也有类似于构造函数的东西。那就是__init__(self,属性),当创建实例时,__init__()方法被自动调用.

    >>> class Person:
        def __init__(self,name,gender,birth):
            self.name = name
            self.gender = gender
            self.birth = birth

    __init__() 方法的第一个参数必须是 self,并且是一定要添加的,如果不添加的话呢我们的系统就无法将参数给对应上,就会导致编译出错

    >>> class Person:
        def __init__(name):
            pass
    
        
    >>> xiao = Person("xiao")
    Traceback (most recent call last):
      File "<pyshell#11>", line 1, in <module>
        xiao = Person("xiao")
    TypeError: __init__() takes 1 positional argument but 2 were given

    我们在对Python进行编程的时候,如果我们类里面的属性不希望被外面看到的话,我们可以用一种方法,对这个属性进行封装。

    如果一个属性由双下划线开头(__),该属性就无法被外部访问。

    >>> class Person(object):
        def __init__(self,name,score):
            self.name = name
            self.__score = score
    
            
    >>> p = Person('Bob',59)
    >>> print (p.name)
    Bob
    >>> try:
        print (p.__score)
    except AttributeError:
        print ("attributeerror")
    
        
    attributeerror

    但是,如果一个属性以"__xxx__"的形式定义,那它又可以被外部访问了,以"__xxx__"定义的属性在Python的类中被称为特殊属性,有很多预定义的特殊属性可以使用,通常我们不要把普通属性用"__xxx__"定义。

    以单下划线开头的属性"_xxx"虽然也可以被外部访问,但是,按照习惯,他们不应该被外部访问。

    实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。

    定义类属性可以直接在 class 中定义:

    >>> class Person(object):
        address = "Earth"
        def __init__(self,name):
            self.name = name
    
            
    >>> print (Person.address)
    Earth
    >>> p1 = Person('Bob')
    >>> print (p1.address)
    Earth

    由于Python是动态语言,类属性也是可以动态添加和修改的:

    >>> Person.address = 'China'
    >>> print (p1.address)
    China

    当实例属性和类属性重名时,实例属性优先级高,它将屏蔽掉对类属性的访问

    >>> p2 = Person('Dean')
    >>> print (p2.address)
    China
    >>> p1.address = 'Japanese'
    >>> print (p1.address)
    Japanese
    >>> print (p2.address)
    China

    在实例上面修改类属性不是更改类的属性,只是给这个类新添加了一个属性而已。

    虽然私有属性无法从外部访问,但是,从类的内部是可以访问的。除了可以定义实例的属性外,还可以定义实例的方法。

    >>> class People(object):
        def __init__(self,name,age):
            self.name = name
            self.__age = age
        def get_age(self):
            return self.__age
    
        
    >>> p1 = People('Dean',16)
    >>> p1.get_age()
    16

    在实例方法内部,可以访问所有实例属性,这样,如果外部需要访问私有属性,可以通过方法调用获得,这种数据封装的形式除了能保护内部数据一致性外,还可以简化外部调用的难度。

    我们在class中定义的实例方法其实也是属性,它实际上是一个函数对象。

    >>> class People(object):
        def __init__(self,name,age):
            self.name = name
            self.__age = age
        def get_age(self):
            return self.__age
    
        
    >>> p1 = People('Dean',16)
    >>> p1.get_age()
    16
    >>> p1.get_age
    <bound method People.get_age of <__main__.People object at 0x0354CE10>>

    因为方法也是一个属性,所以,它也可以动态地添加到实例上,只是需要用 types.MethodType() 把一个函数变为一个方法

    >>> class People(object):
        def __init__(self,name,age):
            self.name = name
            self.__age = age
        def get_age(self):
            return self.__age
    
        
    >>> def fn_get_age(self):
        if self.get_age()>=60:
            return 'old'
        else:
            return 'young'
    
        
    >>> p1 = People('Dean',16)
    >>> p1.term_age = types.MethodType(fn_get_age,p1)
    >>> print (p1.term_age())
    young

    这个是python3.0的写法,如果是2.0的话呢我们就需要一个另外的一种写法:

    import types
    def fn_get_grade(self):
        if self.score >= 80:
            return 'A'
        if self.score >= 60:
            return 'B'
        return 'C'
    
    class Person(object):
        def __init__(self, name, score):
            self.name = name
            self.score = score
    
    p1 = Person('Bob', 90)
    p1.get_grade = types.MethodType(fn_get_grade, p1, Person)
    print p1.get_grade()
    # => A
    p2 = Person('Alice', 65)
    print p2.get_grade()
    # ERROR: AttributeError: 'Person' object has no attribute 'get_grade'
    # 因为p2实例并没有绑定get_grade

    主要的区别是我们的types。MethodType的使用的方法不一样,3.0的版本是需要两个参数,2.0的版本是需要三个参数。

    和属性类似,方法也分实例方法类方法

    通过标记一个 @classmethod,该方法将绑定到 Person 类上,而非类的实例。类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.count 实际上相当于 Person.count

    因为是在类上调用,而非实例上调用,因此类方法无法获得任何实例变量,只能获得类的引用。

    class Person(object):
        count = 0
        @classmethod
        def how_many(cls):
            return cls.count
        def __init__(self, name):
            self.name = name
            Person.count = Person.count + 1
    
    print Person.how_many()
    p1 = Person('Bob')
    print Person.how_many()
  • 相关阅读:
    jquery easy ui 学习 (8)basic treegrid
    jquery easy ui 学习 (7) TreeGrid Actions
    jquery easy ui 学习 (6) basic validatebox
    jquery easy ui 学习 (5) windowlayout
    jquery easy ui 学习 (4) window 打开之后 限制操纵后面元素属性
    提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll
    visual studio 添加虚线的快捷键
    VS2010打开项目时,出现“已经在解决方案中打开了具有该名称的项目”问题的解决方案
    visual studio 编译时 出现 Files 的值 乱码
    微信 连接被意外关闭
  • 原文地址:https://www.cnblogs.com/chang1203/p/5843999.html
Copyright © 2020-2023  润新知