Python面向对象
8.1 类和对象
8.1.1 类的定义
class Student(object):
def _init_(self,name,age):
self.name=name
self.age=age
def study(self,course_name):
print('%s正在学习%s.'%(self.name,course_name))
def watch_movie(self):
if self.age < 18:
print('%s只能观看《熊出没》.'%self.name)
else:
print('%s正在学习Python从小白到大牛.'%self.name)
类的定义与函数的定义一样,只有被执行时才会起作用,因为这种特性,可以将类定义放在if语句的一个分支或函数内部。当解释器执行到类定义时,类定义就产生了一个命名空间,与函数类似。在类内部使用的属性,相当于函数中的变量名,还可以在类的外部继续使用。类的内部与函数的内部一样,相当于一个局部作用域,不同类的内部也可以使用相同的属性名。
8.1.2 对象实例化
Python中所有属性的引用语法为obj.name,有效的属性名称是类对象被创建时存在于类命名空间中的所有名称,因此类定义是这样的。
class Myclass:
i = 12345
def f(self):
return 'hello world'
类属性和变量一样可以被赋值,甚至类本身实例化后也可以赋给某个变量。
x=Myclass()
print(x)
//<_main_.Myclass object at 0x030348F0>
实例化操作会创建一个空的对象,许多人喜欢创建带有特定初始状态的自定义实例,为此类定义可能包含一个名为___init___()的特殊方法。
def _init_(self):
self.data=[]
当一个类定义了init方法时,类的实例化操作会自动为新创建的实例调用init函数,因此可以通过以下语句获得一个已经初始化的新实例。
x=MyClass()
8.1.3 对象的方法
根据定义,一个类中所有是函数对象的属性都是定义了其实例的相应方法。
x.f()
调用一个具有n个参数的方法就相当于调用再多一个参数的对应函数,这个参数值为方法所属实例对象,位置在其他参数之前。
8.1.4 类的变量
在类的定义中,变量分为实例变量和类变量。一般来说,实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法。
class Dog:
kind='canine'
def _init_(self,name):
self.name=name
d=Dog('Fido')
print(d.kind)
//'canine'
print(d.name)
//'Fido'
class Dog:
def _init_(self,name):
self.name=name
self.tricks=[]
def add_trick(self,trick):
self.tricks.append(trick)
d=Dog('Fido')
d.add_trick('roll over')
print(d.tricks)
//['roll over']
类和函数一样,变量是用于传参,也存在生命周期和作用域。类的属性其实也可以做到传参的作用,但是其意义和参数完全不同。
8.2 面向对象编程的三大特性
8.2.1 继承
class Person:
def speak(self):
print "我爱你"
def setHeight(self):
print "身高1.60m."
def breast(self,n):
print "胸围:",n
class Girl(Person):
def setHeight(self):
print "身高1.70m."
if _name_ =="_main_":
cang=Girl()
cang.setHeight()
cang.speak()
cang.breast(100)
class Person:
def eye(self):
print "一双眼睛"
def breast(self,n):
print "胸围:",n
class Girl:
age=28
def color(self):
print "这女孩是白种人"
class HotGirl(Person,Girl):
pass
if _name_ =="_main_":
kong=HotGirl()
kong.eye()
kong.breast(90)
kong.color()
print kong.age
8.2.2 多态
class Animal:
def _init_(self,name=""):
self.name=name
def talk(self):
pass
class Cat(Animal):
def talk(self):
print "Meow!"
class Dog(Animal):
def talk(self):
print "Woof!"
a=Animal()
a.talk()
c=Cat("Missy")
c.talk()
d=Dog("Rocky")
d.talk()
8.2.3 封装
class ProtectMe:
def _init_(self):
self.me="qiwsir"
self._name="kivi"
@property
def name(self):
return self._name
if _name_ =="_main_":
p=ProtectMe()
print p.me
print p.name
8.4 静态方法和类方法
静态方法通过类直接调用而不需要创建对象。静态方法前面需要加上@。
from math import sqrt
class Triangle(object):
def _init_(self,a,b,c):
self._a=a
self._b=b
self._c=c
@staticmethod
def is_valid(a,b,c):
return a+b>c and b+c>a and a+c>b
def perimeter(self):
return self._a+self._b+self._c
def area(self):
half=self.perimeter()/2
return sqrt(half * (half-self._c))
def main():
a,b,c=3,4,5
if Triangle.is_valid(a,b,c):
t=Triangle(a,b,c)
print(t.perimeter())
print(t.area())
else:
print('无法构成三角形.')
if _name_ == '_main_':
main()
类方法的第一个参数约定名cls,它代表的是当前类相关的信息对象,通过这个参数可以获取和类相关的信息并且创建出类的对象。
from time import time,localtime,sleep
class Clock(object):
def _init_(self,hour=0,minute=0,second=0):
self._hour=hour
self._minute=minute
self._second=second
@classmethod
def now(cls):
ctime=localtime(time())
return cls(ctime.tm_hour,ctime.tm_min,ctime.tm_sec)
def run(self):
self._second += 1
if self._second == 60:
self._second=0
self._minute+=1
if self._minute ==60:
self._minute=0
self._hour += 1
if self._hour == 24:
self._hour=0
def show(self):
return '%02d:%02d:%02d'% \ (self._hour,self._minute,self._second)
def main():
clock=Clock.now()
while True:
print(clock.show())
sleep(1)
clock.run()
if _name_ == '_main_':
main()
普通实例方法的第一个参数需要是self,它表示一个具体的实例本身;如果用了静态方法就可以无视这个self,而将这个方法当成一个普通的函数使用;对于类方法,它的第一个参数不是self,而是cls,它表示这个类本身。