• python——面向对象编程


    面向对象的基本思想:

         1.  用于定义抽象的类型, 实例根据类的定义被创建

    python之定义类并创建实例

       

    在Python中,类通过 class 关键字定义。以 Person 为例,定义一个Person类如下:

    class Person(object):
        pass

    按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的

     class Person():
      pass
     

    python中创建实例属性

    如何让每个实例拥有各自不同的属性?由于Python是动态语言,对每一个实例,都可以直接给他们的属性赋值,

    例如,给xiaoming这个实例加上name、genderbirth属性:

     
    xiaoming = Person()
    xiaoming.name = 'Xiao Ming'
    xiaoming.gender = 'Male'
    xiaoming.birth = '1990-1-1'

    xiaohong加上的属性不一定要和xiaoming相同:

    xiaohong = Person()
    xiaohong.name = 'Xiao Hong'
    xiaohong.school = 'No. 1 High School'
    xiaohong.grade = 2



    class Person(object):
        pass
    p1 = Person()
    p1.name = 'Bart'
    p2 = Person()
    p2.name = 'Adam'
    p3 = Person()
    p3.name = 'Lisa'
    L1 = [p1, p2, p3]
    L2 = sorted(L1, lambda p1,p2:cmp(p1.name, p2.name))
    print L2[0].name
    print L2[1].name
    print L2[2].name

    python中初始化实例属性

    我们可以自由地给一个实例绑定各种属性,但是,现实世界中,一种类型的实例应该拥有相同名字的属性。例如,Person类应该在创建的时候就拥有 name、gender 和 birth 属性,怎么办?

    在定义 Person 类时,可以为Person类添加一个特殊的__init__()方法,当创建实例时,__init__()方法被自动调用,我们就能在此为每个实例都统一加上以下属性:

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

    __init__() 方法的第一个参数必须是 self(也可以用别的名字,但建议使用习惯用法),后续参数则可以自由指定,和定义函数没有任何区别。

    class Person(object):
        def __init__(self,name,gender,birth,*args,**kw):
            self.name=name
            self.gender=gender
            self.birth=birth
            for i in args:
                print i
            for k,v in kw.items():
                setattr(self,k,v)
    xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', '33',job='Student')
    print xiaoming.name
    print xiaoming.job
     

    Python参数组合

    参数定义的顺序必须是:①必选参数、②默认参数、③可选参数、④命名关键字参数、⑤关键字参数

     
     #参数定义的顺序必须是:必选参数、默认参数、可选参数、命名关键字参数、关键字参数
    6 def f2(a,b,c=0,*,d,**kw):
    7     print('a=','b=',b,'c=','d=',d,'kw=',kw)
     

    python中访问限制

    Python对属性权限的控制是通过属性名来实现的,如果一个属性由双下划线开头(__),该属性就无法被外部访问

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

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

     class Person(object):
        def __init__(self,name):
            self.name=name
            self._title='Mr'
            self.__job = 'Student'
    p=Person('Bob')
    print (p.name)
    print (p._title)
    print (p.job)

    Bob
    Mr
    Traceback (most recent call last):
      File "D: est2.py", line 396, in <module>
        print (p.job)
    AttributeError: 'Person' object has no attribute 'job

     

    python中创建类属性

    类是模板,而实例则是根据类创建的对象。

    绑定在一个实例上的属性不会影响其他实例,但是,类本身也是一个对象,如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个!也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。

     class Person(object):
        address = 'Earth'
        def __init__(self,name):
            self.name=name
    p=Person('test')
    print (p.name)
    print (p.address)  所有实例都可以访问到它所属的类的属性:
    print (p.name)

    >>Earth
    >>test

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

    Person.address = 'China'
    print p1.address
    # => 'China'
    print p2.address
    # => 'China'

    因为类属性只有一份,所以,当Person类的address改变时,所有实例访问到的类属性都改变了。

    类属性也是可以动态添加:

    Person.age=25
    print (p.age)

    >>25

    请给 Person 类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Person 的实例:

    class Person(object):
        count=0
        def __init__(self,name):
            self.name=name
            Person.count=Person.count+1
    p1 = Person('Bob')
    print Person.count
    p2 = Person('Alice')
    print Person.count
    p3 = Person('Tim')
    print Person.count

    python中类属性和实例属性名字冲突怎么办

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

     
    class Person(object):
        __count = 0
        def __init__(self, name):
            self.name=name
            Person.__count=Person.__count+1
            print Person.__count  :可以访问
    p1 = Person('Bob')
    p2 = Person('Alice')
    #print Person.__count  : 外部无法访问
     
    私有属性无法从外部访问,但是,从类的内部是可以访问的
     

    python中定义实例方法

     
    class Person(object):
    
        def __init__(self, name):
            self.__name = name
    
        def get_name(self):
            return self.__name

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

    python中方法也是属性

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

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

     
    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'




    由于属性可以是普通的值对象,如 str,int 等,也可以是方法,还可以是函数,大家看看下面代码的运行结果,
    请想一想 p1.get_grade 为什么是函数而不是方法:


    class Person(object):
        def __init__(self, name, score):
            self.name = name
            self.score = score
            self.get_grade = lambda: 'A'
    p1 = Person('Bob', 90)
    print p1.get_grade
    print p1.get_grade()
     
    直接把 lambda 函数赋值给 self.get_grade 和绑定方法有所不同,函数调用不需要传入 self,但是方法调用需要传入 self
     

    python中定义类方法

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

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

     

    要在class中定义类方法,需要这么写:

    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


    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()  通过类方法获取类的私有变量。
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
  • 相关阅读:
    map的集合顺序怎么跟添加时候的顺序一样
    陕西电信开出的电子发票没有发票代码
    微擎密码忘了,password.php也不起作用
    使用composer require安装服务后 切记使用composer install 安装一下才能用
    激活 山东理工大学 jetrbins
    SpringBoot打包成可执行jar
    卸载windows服务
    cglib的动态代理
    cglib的使用
    FCKeditor使用
  • 原文地址:https://www.cnblogs.com/ting152/p/12935092.html
Copyright © 2020-2023  润新知