• 面向对象编程


    创建类:

    class Person(object):
        pass
    
    xiaoming = Person()
    xiaohong = Person()
    
    print xiaoming
    print xiaohong
    print xiaoming==xiaohong

     创建实例属性:Python是动态语言,对每一个实例,都可以直接给他们的属性赋值,实例的属性可以像普通变量一样进行操作。

    #xiaoming和xiaohong是同一个类的对象
    xiaoming = Person()
    xiaoming.name = 'Xiao Ming'
    xiaoming.gender = 'Male'
    xiaoming.birth = '1990-1-1'
    
    
    xiaohong = Person()
    xiaohong.name = 'Xiao Hong'
    xiaohong.school = 'No. 1 High School'
    xiaohong.grade = 2
    
    
    xiaohong.grade = xiaohong.grade + 1

    初始化实例属性:__init__()方法,创建实例时,该方法自动调用

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

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

         以"__xxx__"定义的属性在Python的类中被称为特殊属性,有很多预定义的特殊属性可以使用,通常我们不要把普通属性用"__xxx__"定义。

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

    类属性:实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。

    class Person(object):
        address = 'Earth'
        def __init__(self, name):
            self.name = name

    当实例属性和类属性重名时,实例属性优先级高。要在实例上修改类属性,它实际上并没有修改类属性,而是给实例绑定了一个实例属性。

    class Person(object):
        address = 'Earth'
        def __init__(self, name):
            self.name = name
    
    p1 = Person('Bob')
    p2 = Person('Alice')
    
    print 'Person.address = ' + Person.address
    
    p1.address = 'China'
    print 'p1.address = ' + p1.address
    
    print 'Person.address = ' + Person.address
    print 'p2.address = ' + p2.address

    结果:

    Person.address = Earth
    p1.address = China
    Person.address = Earth
    p2.address = Earth

    定义实例方法:

    • 一个实例的私有属性就是以__开头的属性,无法被外部访问,可以在类的内部访问
    • 实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的
    class Person(object):
    
        def __init__(self, name):
            self.__name = name
    
        def get_name(self):
            return self.__name
    •  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'
      # 因为p2实例并没有绑定get_grade
    • 函数调用不需要传入 self,但是方法调用需要传入 self。

    定义类方法:通过标记一个 @classmethod,该方法将绑定到类上,而非类的实例。

    • 类方法无法获得任何实例变量,只能获得类的引用。
    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()

    继承:

    class Person(object):
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
    class Teacher(Person):
    
        def __init__(self, name, gender, course):
            super(Teacher,self).__init__(name,gender)
            self.course=course
    
    t = Teacher('Alice', 'Female', 'English')
    print t.name
    print t.course

    isinstance():判断变量的类型

      isinstance(t,Person)   判断t是不是Person类实例

    多态:对于同一方法,根据调用者不同而产生不同结果

    多重继承:继承多个父类

    多重继承通过 super()调用__init__()方法时,A 虽然被继承了两次,但__init__()只调用一次

    class D(B, C):
        def __init__(self, a):
            super(D, self).__init__(a)
            print 'init D...'

     获取对象信息:

    • type()函数获取类型   
      >>> type(123)
      <type 'int'>
    •  dir() 函数获取变量的所有属性
      >>> dir(123)   # 整数也有很多属性...
      ['__abs__', '__add__', '__and__', '__class__', '__cmp__', ...]
    •  getattr() 和 setattr():已知一个属性名称,要获取或者设置对象的属性
      getattr(s, 'name')  # 获取name属性
      setattr(s, 'name', 'Adam')  # 设置新的name属性

     特殊方法:

    __str__():print自动调用,用于显示给用户

    __repr__():用于显示给开发人员

    __cmp__():sorted()函数按照默认__cmp__()函数进行排序

    class Student(object):
    
        def __init__(self, name, score):
            self.name = name
            self.score = score
    
        def __str__(self):
            return '(%s: %s)' % (self.name, self.score)
    
        __repr__ = __str__
    
        def __cmp__(self, s):
            if self.score > s.score:
                return -1
            elif self.score == s.score:
                if self.name < s.name:
                    return -1
                else:
                    return 1
            else:
                return 1
    
    L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 99)]
    print sorted(L)

    __len__():返回元素个数,len()函数调用

    class Fib(object):
        L=[0,1]
    
        def __init__(self, num):
            for i in range(2,num):
                j=Fib.L[i-1]+Fib.L[i-2]
                Fib.L.append(j)
    
        def __len__(self):
            return len(Fib.L)
        
        def __str__(self):
            return str(Fib.L)
    
    f = Fib(10)
    print f
    print len(f)
    def gcd(a, b):
        if b == 0:
            return a
        return gcd(b, a % b)
        
    class Rational(object):
        def __init__(self, p, q):
            self.p = p
            self.q = q
    
        def __add__(self, r):
            return Rational(self.p * r.q + self.q * r.p, self.q * r.q)
    
        def __sub__(self, r):
            return Rational(self.p * r.q - self.q * r.p, self.q * r.q)
    
        def __mul__(self, r):
            return Rational(self.p * r.p , self.q * r.q)
    
        def __div__(self, r):
            return Rational(self.p * r.q , self.q * r.p)
    
        def __str__(self):
            g = gcd(self.p, self.q)
            return '%s/%s' % (self.p/g,self.q/g)
            
        __repr__ = __str__
    
    r1 = Rational(1, 2)
    r2 = Rational(1, 4)
    print r1 + r2
    print r1 - r2
    print r1 * r2
    print r1 / r2

    __int__():int()函数自动调用

    __float__():float()函数自动调用

    @property:

    • 重新实现一个属性的setter和getter方法
    class Student(object):
        def __init__(self, name, score):
            self.name = name
            self.__score = score
        @property
        def score(self):
            return self.__score
        @score.setter
        def score(self, score):
            if score < 0 or score > 100:
                raise ValueError('invalid score')
            self.__score = score
    • 将一个方法 转换为只读属性
    class Student(object):
    
        def __init__(self, name, score):
            self.name = name
            self.__score = score
    
        @property
        def score(self):
            return self.__score
    
        @score.setter
        def score(self, score):
            if score < 0 or score > 100:
                raise ValueError('invalid score')
            self.__score = score
    
        @property
        def grade(self):
            if self.score>=80:
                return 'A'
            elif self.score<60:
                return 'C'
            else:
                return 'B'
    
    s = Student('Bob', 59)
    print s.grade
    
    s.score = 60
    print s.grade
    
    s.score = 99
    print s.grade

    __slots__:一个类允许的属性列表,限制当前类能拥有的属性

    class Person(object):
    
        __slots__ = ('name', 'gender')
    
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
    class Student(Person):
    
        __slots__ = ('score',)  #在Person类的基础上增加score属性
    
        def __init__(self,name,gender,score):
            super(Student,self).__init__(name,gender)
            self.score=score
            
    
    s = Student('Bob', 'male', 59)
    s.name = 'Tim'
    s.score = 99
    print s.score

    __call__:把一个实例变成可调用对象需要实现的方法

    class Fib(object):
        def __call__(self, num):
            a, b, L = 0, 1, []
            for n in range(num):
                L.append(a)
                a, b = b, a + b
            return L
    
    f = Fib()
    print f(10)
  • 相关阅读:
    亿级流量架构服务降级,写得太好了!
    面试官:什么是对象池?有什么用?别说你还不会!
    最新数据库排行榜出炉!MySQL 稳了~
    别再写满屏的 get & set 了,太 Low!试试 MapStruct 高级玩法!
    vista 中php4, php5 共存
    dotnet framework 3.5 installed issues on nonenglish os
    web service notes
    msn web status
    db notes
    wikipedia的mysql utf8中文在.net中的处理
  • 原文地址:https://www.cnblogs.com/HJhj/p/7250779.html
Copyright © 2020-2023  润新知