面向对象编程
class 定义类,类的值可以修改
_ _init_ _(self) 初始化函数,创建类时自动调用
self 指向对象本身,可以用其他的名字 但不建议
#person.py class Person: """Class to represent a person""" def __init__(self): self.name = '' self.age = 0
>>> p = Person() >>> p <__main__.Person object at 0x022467B0> >>> p.age 0 >>> p.name '' >>> p.age = 55 >>> p.age 55
显示对象:
可以用print来打印,也可以用__str__ 注意两者的调用方式不同。
def display(self): print("Person('%s',%d)" % (self.name,self.age)) def __str__(self): return "Person('%s',%d)" % (self.name,self.age) def display2(self): print(str(self))
>>> p.display() Person('',0) >>> str(p) "Person('',0)" >>> p.display2() Person('',0)
官方表示:__repr__ 就是直接输入对象时的显示,建议显示创建对象时所需要的代码 如果定义了__repr__但没有定义__str__,则调用str()时会显示repr()的内容。
#person.py class Person: """Class to represent a person""" def __init__(self): self.name = '' self.age = 0 def display(self): print("Person('%s',%d)" % (self.name,self.age)) def __str__(self): return "Person('%s',%d)" % (self.name,self.age) def display2(self): print(str(self)) def __repr__(self): return str(self)
>>> p = Person() >>> p Person('',0)
初始化:
可在__init__函数中初始化对象,可以有默认值,但不建议用默认值,因为需要在之后的使用中加入检查
def __init__(self, name = '', age = 0): self.name = name self.age = age
>>> p = Person() >>> p Person('',0) >>> p = Person('Ann', 15) >>> p Person('Ann',15)
设置函数与获取函数:
可以防止设置不合理的值:
def set_age(self,age): if 0 < age <=150: self.age = age
>>> p = Person("Andy",20) >>> p Person('Andy',20) >>> p.set_age(1000) >>> p Person('Andy',20) >>> p.set_age(40) >>> p Person('Andy',40)
也可以使用特性装饰器
需要用@修饰,修改变量的语法可以变简单 看得不是很懂http://www.open-open.com/lib/view/open1395285030019.html中给出了一些解释
@property def age(self): return self._age @age.setter def age(self, age): if 0 < age <= 150: self._age = age
>>> p = Person('Peter', 18) >>> p Person('Peter',18) >>> p.age = 150 >>> p Person('Peter',150) >>> p.age = -3 >>> p Person('Peter',150)
私有变量:用双下划线开始的变量为私有变量 访问私有变量需要加上_类名称 可以防止意外修改变量 建议最开始将变量都设为私有,之后再用充分的理由转为公有
#person.py class Person: """Class to represent a person""" def __init__(self, name = '', age = 0): self.__name = name self.__age = age def display(self): print("Person('%s',%d)" % (self.__name,self.__age)) def __str__(self): return "Person('%s',%d)" % (self.__name,self.__age) def display2(self): print(str(self)) def __repr__(self): return str(self) def set_age(self,age): if 0 < age <=150: self.__age = age @property def age(self): return self.__age @age.setter def age(self, age): if 0 < age <= 150: self.__age = age
>>> p = Person('a',2) >>> p Person('a',2) >>> p.__age = 4 >>> p Person('a',2) >>> p._Person__age = 4 >>> p Person('a',4)
继承:
class 类名(父类名):
pass
用新的类继承父类,pass表示什么也不做。也可以重写父类中的函数
#players.py class Player: def __init__(self, name): self._name = name self._score = 0 def reset_score(self): self._score = 0 def incr_score(self): self._score = self._score + 1 def get_name(self): return self._name def __str__(self): return "name = '%s', score = %s" % (self._name, self._score) def __repr__(self): return 'Player(%s)' % str(self) class Human(Player): def __repr__(self): return 'Human(%s)' % str(self) class Computer(Player): def __repr__(self): return 'Computer(%s)' % str(self)
>>> p = Player('Peter') >>> p Player(name = 'Peter', score = 0) >>> h = Human('Wang') >>> h Human(name = 'Wang', score = 0) >>> c = Computer('Cob') >>> c Computer(name = 'Cob', score = 0)
多态:同一函数不同的实现方法
下面编写一个简单游戏,两个人选择数字,谁选择的数比另一个人的小1则获胜
get_move函数采用多态 play_undercut返回三元组 可以传入两个人类玩家 两个计算机玩家 或是一个人类玩家和一个计算机玩家
#players.py class Player: def __init__(self, name): self._name = name self._score = 0 def reset_score(self): self._score = 0 def incr_score(self): self._score = self._score + 1 def get_name(self): return self._name def __str__(self): return "name = '%s', score = %s" % (self._name, self._score) def __repr__(self): return 'Player(%s)' % str(self) def play_undercut(p1,p2): p1.reset_score() p2.reset_score() m1 = p1.get_move() m2 = p2.get_move() print("%s move %s" % (p1.get_name(), m1)) print("%s move %s" % (p2.get_name(), m2)) if m1 == m2 - 1: p1.incr_score() return p1,p2,'%s wins!' % p1.get_name() elif m2 == m1 - 1: return p1,p2,'%s wins!' % p2.get_name() else: return p1,p2,'draw: no winner' class Human(Player): def __repr__(self): return 'Human(%s)' % str(self) def get_move(self): while True: try: n = int(input('%s move(1 - 10): ' %self.get_name())) if 1 <= n <= 10: return n else: print('Oops!') except: print('Oops!') import random class Computer(Player): def __repr__(self): return 'Computer(%s)' % str(self) def get_move(self): return random.randint(1,10)
>>> c = Computer('Cook') >>> h = Human('Man') >>> play_undercut(c,h) Man move(1 - 10): 1 Cook move 5 Man move 1 (Computer(name = 'Cook', score = 0), Human(name = 'Man', score = 0), 'draw: no winner')