面向对象这种编程的范式每个语言都是通用的,这里总结一下python的面向对象语法,主要包含以下几个方面!
1 基本语法
# 定义类 class Person(object): n = 10 # 类变量,所有实例共享 # 构造方法,self为创建的实例本身,即hou,yao等 def __init__(self, name, sex, age = 25): # 指定默认属性,可不传 self.name = name # 实例变量,属于实例 self.sex = sex self.age = age # self为调用实例本身 def work(self): print("%s 的年龄是 %s,性别%s,正在工作" % (self.name, self.age, self.sex)) def eat(self, food): print("{NAME} 吃了 {FOOD}".format(NAME=self.name, FOOD=food)) # 实例类的对象 hou = Person("侯征", "男", 30) print(Person.n) # 10 print(hou.n) # 10,会先从实例变量中找,找不到再去类变量找 hou.n = 30 print(hou.n) # 30 yao = Person("姚振", "女") he = Person("何毅", 1) # 调用类的函数时,python会自动把调用者传递到参数中,即 Person.work(hou) hou.work() yao.work() he.eat("肉夹馍")
2 实例变量与私有变量
class Dog(object): master = "侯征" # 类变量,属于类 def __init__(self, name): # 实例变量,属于实例 self.name = name def bite(self, someone): print("%s 的狗要咬%s了" %(self.master, someone)) # 对象销毁时候执行 del 实例 或者 程序停止 def __del__(self): print(self.name+"died") yao = Dog("姚振") print(Dog.master) # 实例可直接使用类变量,会先从实例变量找,没有去类变量找 print(yao.master) yao.master = "何毅" # 覆写类变量,在实例中创建一个新变量进行赋值,不会改变类变量 print(yao.master) del yao.master print(yao.master) yao.age = 12 # 添加新属性 print(yao.age)
3 私有属性与私有方法
class Cat(object): def __init__(self, name, age): self.name = name # 前面加__声明属性为私有属性,只能内部函数访问 self.__age = age def eat(self): # 内部可以访问私有属性 print("%s吃东西,它今年%s岁" % (self.name,self.__age)) # 可以执行私有方法 self.__slepp() # 前面加__ 声明方法为私有方法 def __slepp(self): print("%s 睡觉" % self.name) cat = Cat("小花",5) # print(cat.__age) 无法直接访问 cat.eat()
4 继承
# 父类 class Person(object): def __init__(self, name, age): self.name = name self.age = age def eat(self): print("%s 吃饭" %self.name) # 继承Person类 class Man(Person): def __init__(self, name, age, goatee): super().__init__(name, age) # 调用父类构造方法 # Person.__init__(self, name, age) # 添加新的属性 self.goatee = goatee # 添加新的方法 def playgame(self): print("打游戏") class Woman(Person): # 添加自己方法 def watchShow(self): print("看电视") # 覆写父类方法 def eat(self): super().eat() # 调用父类方法 print("%s 还要吃减肥餐"%self.name) m1 = Man("heyi", 25, 2) print(m1.name) m1.eat() # 可直接调用父类方法,已继承 w1 = Woman("yaozhen",25) w1.eat()
5 多态
# 多态 class Animal(object): def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): print('%s: 喵喵喵!' % self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' % self.name) def func(obj): # 一个接口,多种形态 obj.talk() # 传入哪个对象,调用那个对象的方法 c1 = Cat('小晴') d1 = Dog('李磊') func(c1) func(d1)
6 静态方法,类方法,属性方法
# 静态方法 class Person(object): type = "中国人" def __init__(self, name): self.name = name @staticmethod # 静态方法装饰器 def eat(self): print("调用静态方法,%s" %self.name) @classmethod # 类方法装饰器 def run(self): # 类方法只能访问类属性,无法访问实例属性 print("调用类方法,类属性:%s" %self.type) @property # 属性方法装饰器 def do(self): self.eat(self) self.run() person = Person("侯征") person.do # 属性方法只能直接调用,不需要() person.run() # 调用静态方法时,不会把自身当做实例自动传递,需要手动添加实例 person.eat(person)
7 特殊方法
# 类的特殊成员方法 class Person(object): """ 这是一个描述人的python类 """ age = 25 def __init__(self, name): self.name = name # 想调用需要定义 def __call__(self, *args, **kwargs): print("-----") p = Person("houzheng") # 类的描述信息 print(p.__doc__) # 表示当前操作的对象在那个模块 print(p.__module__) # 表示当前操作的对象的类是什么 print(p.__class__) # <class '__main__.Person'> p() # 需要在类中定义 print(p.__dict__) # 实例调用返回实例属性 {'name': 'houzheng'} print(Person.__dict__) # 类调用返回类属性和所有方法 print(p.__str__) # 打印方法,即 toString,可覆写
8 反射
# 反射 class Foo(object): def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' obj = Foo() # #### 检查是否含有成员 #### hasattr(obj, 'name') hasattr(obj, 'func') # #### 获取成员 #### getattr(obj, 'name') getattr(obj, 'show') # #### 设置成员 #### setattr(obj, 'age', 18) # 可以设置方法 setattr(obj, 'show', lambda num: num + 1) # #### 删除属性,不能删除方法 #### delattr(obj, 'name') print(obj.show(2))