#面向对象 class Tortoise: bodyColor = "绿色" footNum = 4 weight = 10 hasShell = True #会爬 def crawl(self): print("乌龟会爬") #会吃东西 def eat(self): print("乌龟会吃东西") #会睡觉 def sleep(self): print("乌龟会睡觉") class Person : name = "lisi" age = 18 def __init__(self,name,age): self.name = name #若没有这行,对象.name将返回类变量lisi self.age = age #若没有这行,对象.age将返回类变量18 print("创建实例!这个人的名字是:",name,"年龄为:",age) def say(self,content): print(content) p1 = Person("梦竹",23) #创建类对象 print(p1.name,p1.age) #调用实例变量,查询 p1.name = "给队友一个助攻" #实例变量赋值,修改 p1.say("我又选择了螳螂") #调用方法 print(p1.name,p1.age) p1.skills = ["swimming","programming"] #增加实例变量 print(p1.skills) # del p1.name #删除实例变量 #为对象动态添加方法,方法只对该对象有效 def info(self): #定义一个函数 print("--info函数--",self) p1.foo = info #将该函数赋值给p1的foo方法 p1.foo(p1) #手动为第一个参数传入参数值 #使用lambda为对象动态添加方法 p1.bar = lambda self : print("--info函数--",self) p1.bar(222) #手动为第一个参数传入参数值 #助于 types 模块下的 MethodType , def intro_func(self, content): print("我是%s ,信息为:%s" % (self.name,content)) from types import MethodType # 导入MethodType p1.intro = MethodType(intro_func, p1) # 使用MethodType对intro_func进行包装,将该函数的第一个参数绑定为p1 p1.intro("生活在别处") # 第一个参数已经绑定了,无需传入 print(type(p1)) #为类添加方法 __slots__ 限制了能动态添加的是属性名和方法名 class Dog: __slots__ = ('walk', 'age', 'name') def __init__(self, name): self.name = name def test(self): print('预先定义的test方法') def walk_func(self): print('%s慢慢地走过一片草地' % self.name) d1 = Dog('Snoopy') #创建 d2 = Dog('Snoopy2') d1.age = 5 Dog.walk = walk_func d1.test() d1.walk() d2.walk() #self class ReturnSelf : def grow(self): if hasattr(self, 'age'): self.age += 1 else: self.age = 1 # return self返回调用该方法的对象 return self rs = ReturnSelf() # 可以连续调用同一个方法 rs.grow().grow().grow() print("rs的age属性值是:", rs.age) #类方法/静态方法 class Bird: @classmethod # @classmethod 修饰的方法是类方法 fly def fly(cls): print('类方法fly:',cls) Bird.fly() #调用类方法 class Bird: @staticmethod # @staticmethod 修饰的方法是静态方法 fly def fly(p): print('静态方法fly:',p) Bird.fly() # fly不是类方法,不能直接调 Bird.fly("类名") #调用静态方法 bird = Bird() bird.fly("类对象") #对象调用静态方法 #类中需要定义get del set等操作 class Rectangle: # 定义构造方法 def __init__(self, width, height): self.width = width self.height = height # 定义setsize()函数 def setsize (self , size): self.width, self.height = size # 定义getsize()函数 def getsize (self): return self.width, self.height # 定义delsize()函数 def delsize (self): self.width, self.height = 0, 0 rect = Rectangle(3 , 4) rect.setsize((6,8)) print(rect.getsize()) #使用property() class Rectangle: # 定义构造方法 def __init__(self, width, height): self.width = width self.height = height # 定义setsize()函数 def setsize (self , size): self.width, self.height = size # 定义getsize()函数 def getsize (self): return self.width, self.height # 定义getsize()函数 def delsize (self): self.width, self.height = 0, 0 # 使用property定义属性 size = property(getsize, setsize, delsize, '用于描述矩形大小的属性') # 访问size属性的说明文档 print(Rectangle.size.__doc__) # 通过内置的help()函数查看Rectangle.size的说明文档 help(Rectangle.size) rect = Rectangle(4, 3) # 创建实例 print(rect.size) # (4, 3) rect.size = 9, 7 # 对rect的size属性赋值 print(rect.width) # 9 # 访问rect的width、height实例变量 print(rect.height) # 7 # 访问rect的width、height实例变量 del rect.size # 删除rect的size属性 print(rect.width) # 0 # 访问rect的width、height实例变量 print(rect.height) # 0 ####所有的get del set 都用对象.size 来操作 #封装 #将__hide,__name,__age 隐藏起来,只能使用property的name和age,就是调用setname等 class User : def __hide(self): print('示范隐藏的hide方法') def getname(self): return self.__name def setname(self, name): if len(name) < 3 or len(name) > 8: raise ValueError('用户名长度必须在3~8之间') self.__name = name name = property(getname, setname) def setage(self, age): if age < 18 or age > 70: raise ValueError('用户名年龄必须在18在70之间') self.__age = age def getage(self): return self.__age age = property(getage, setage) # 创建User对象 u = User() u.name = 'fkit'# 对name属性赋值,实际上调用setname()方法 u.age = 25 print(u.name) # fkit print(u.age) # 25 #u.__name 调不到,u._User__name可以绕过隐藏 #继承 class Fruit: def info(self): print("我是一个水果!重%g克" % self.weight) class Food: def taste(self): print("不同食物的口感不同") class Apple(Fruit, Food): # 定义Apple类,继承了Fruit和Food类 pass a = Apple() # 创建Apple对象 a.weight = 5.6 #添加了一个实例变量 a.info() # 调用Apple对象的info()方法 a.taste() # 调用Apple对象的taste()方法 #重写父类方法 class Bird: def fly(self): print("我在天空里自由自在地飞翔...") class Ostrich(Bird): def fly(self): print("我只能在地上奔跑...") # 重写Bird类的fly()方法,方法覆盖 def foo(self): Bird.fly(self) os = Ostrich() # 创建Ostrich对象 os.fly() # 执行Ostrich对象的fly()方法,调用的是子类重写的方法,子类的方法覆盖了父类的方法 os.foo() #调用父类被重写的方法 Bird.fly(os) #调用父类被重写的方法 #super() 多父类,构造方法重写 class Employee : def __init__ (self, salary): self.salary = salary def work (self): print('普通员工正在写代码,工资是:', self.salary) class Customer: def __init__ (self, favorite, address): self.favorite = favorite self.address = address def info (self): print('我是一个顾客,我的爱好是: %s,地址是%s' % (self.favorite, self.address)) class Manager(Employee, Customer): # Manager继承了Employee、Customer def __init__(self, salary, favorite, address): # 重写父类的构造方法 print('--Manager的构造方法--') super().__init__(salary) # 通过super()函数调用父类的构造方法 #super(Manager, self).__init__(salary) # 使用未绑定方法调用父类的构造方法 Customer.__init__(self, favorite, address) # 创建Manager对象 m = Manager(25000, 'IT产品', '广州') m.work() #① m.info() #② #type class Role: pass r = Role() print(type(r)) # <class '__main__.Role'> 对象类型显示为 __main__.类名 print(type(Role)) # <class 'type'> 类的类型为type #特殊方法hasattr getattr setattr isinstance class Comment: def __init__(self, detail, view_times): self.detail = detail self.view_times = view_times def info(): print("一条简单的评论,内容是%s" % self.detail) c = Comment('疯狂Python讲义很不错', 20) print(hasattr(c, 'detail')) # True # 判断是否包含指定的属性或方法 print(getattr(c, 'detail')) # '疯狂Python讲义很不错' # 获取指定属性的属性值 setattr(c, 'detail', '天气不错') # 为指定属性设置属性值 isinstance(c, Comment) issubclass(Manager,Employee)