#面向对象
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)) # 对象类型显示为 __main__.类名
print(type(Role)) # 类的类型为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)