面向对象编程
Posted HHello_World
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象编程相关的知识,希望对你有一定的参考价值。
创建类:
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)
以上是关于面向对象编程的主要内容,如果未能解决你的问题,请参考以下文章