面向对象编程

创建类:

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)
原文地址:https://www.cnblogs.com/HJhj/p/7250779.html