类属性:属于类的成员,对象共有的
修改方式 : 1. 类名.类属性=... 2. 实例对象.__class__类属性=...
class Preson:
def __init__(self):
self.name='无名氏'
self.age=18
def show(self):
print('姓名: '+self.name+' 年龄: '+str(self.age))
if __name__=='__main__':
#1. 类名.类属性=...
Preson.height='178cm'
zhangsan=Preson()
zhangsan.name
zhangsan.age
zhangsan.show()
# 2.实例对象.__class__类属性=...
zhangsan.__class__.phone='119110120'
print(zhangsan.__class__.phone)
print(zhangsan.height)
lisi=Preson()
lisi.name='李四'
lisi.age='20'
lisi.show()
print(zhangsan.__class__.phone) #全局共有
print(zhangsan.height)
输出结果为:
类方法:在方法上添加 @classmethod --> 是一个装饰器
可以通过类方法调用类属性,也可以通过对象调用类属性
class Preson:
@classmethod
#类方法更倾向于 工具方法 不需要重复创建对象 不是以对象形式去调用
def show(cls): #括号里面的值建议 见名知意 直接填写cls
print('这是一个类方法....')
Preson.show() #通过类方法直接调用
Pre=Preson()
Pre.show() #也可以通过对象方法调用
#均打印为: 这是一个类方法....
# 这是一个类方法....
静态方法:
方法前加 @staticmethod 静态方法可以加参数,
静态方法既和类没关系,也和对象没关系,也可以通过类和对象调用
#无参的情况下:
class Preson:
@staticmethod
def show(): #括号里面可以什么都不添加, 如果添加 ,下面调取时也应该添加(可以添加任意值)
print('这是一个静态方法....')
Preson.show() #通过类方法直接调用
Pre=Preson()
Pre.show() #通过对象方法调用
#打印为: 这是一个静态方法....
# 这是一个静态方法....
#带参情况:
class Preson:
@staticmethod
def show(date):
print(date+' 今天天气不错....')
Preson.show('具体日期') #通过类方法直接调用
Pre=Preson()
Pre.show('5-13') #通过对象方法调用
#打印为: 具体日期 今天天气不错....
# 5-13 今天天气不错....
继 承 :
子类继承父类,子类可以使用父类的属性和方法,简化代码.
当生成子类对象时,先初始化父类对象,
所以如果父类有__init__()方法,并且有属性时,要通过子类的构造赋值
一个类可以有多个子类
子类继承父类时,第一种方法: super().__init__(self,属性)
class Pet: #父类
def __init__(self,name,love,health):
self.name=name
self.love=love
self.health=health
def show(self):
print('宠物名: '+self.name+' 亲密度: ',self.love,'健康值: ',self.health)
class Dog(Pet): #继承时括号里面写父类
def __init__(self, name, love, health):
super().__init__(name, love, health) #这里 直接输入参数即可 不需要填self
def eat(self):
print(self.name + '正在吃饭...')
dog=Dog('Boss',60,90) #这里面可以赋值 写需要的参数
dog.eat()
dog.show()
#打印为 Boss正在吃饭...
# 宠物名: Boss 亲密度: 60 健康值: 90
子类继承父类时,第二种方法: 父类.__init__(self,参数)==>父类.__init__(self)-->调用无参
class Pet:
def __init__(self,name,love,health):
self.name=name
self.love=love
self.health=health
def show(self):
print('宠物名: '+self.name+' 亲密度: ',self.love,'健康值: ',self.health)
class Dog(Pet): #继承时括号里面写父类
def __init__(self, name, love, health):
Pet.__init__(self,name, love, health) #这里需要在括号内输入self,然后再输入参数
def eat(self):
print(self.name + '正在吃饭...')
dog=Dog('Boss',60,90) #这里面可以赋值 写需要的参数
dog.eat()
dog.show()
#打印为 Boss正在吃饭...
# 宠物名: Boss 亲密度: 60 健康值: 90
子类继承父类时,第三种方法: super(子类,self).__init__(参数)
class Pet:
def __init__(self,name,love,health):
self.name=name
self.love=love
self.health=health
def show(self):
print('宠物名: '+self.name+' 亲密度: ',self.love,'健康值: ',self.health)
class Dog(Pet): #继承时括号里面写父类
def __init__(self, name, love, health):
super(Dog,self).__init__(name, love, health)
def eat(self):
print(self.name + '正在吃饭...')
dog=Dog('Boss',60,90) #这里面可以赋值 写需要的参数
dog.eat()
dog.show()
#打印为 Boss正在吃饭...
# 宠物名: Boss 亲密度: 60 健康值: 90
总结:当子类继承父类时,子类的构造方法应该包含父类和子类共同的属性,在子类的初始化__init__()方法中,将父类的属性传递给父类,子类的属性赋值给子类
方法重写:子类继承父类时,子类的方法签名和父类一样,此时子类重写了父类的方法,当生成子类对象时,调用的是子类重写的方法.
继承特性之一:传递性(层层传递)
class Pet:
def __init__(self,name,love,health):
self.name=name
self.love=love
self.health=health
def show(self):
print('宠物名: '+self.name+' 亲密度: ',self.love,'健康值: ',self.health)
class Dog(Pet): #继承时括号里面写父类
def __init__(self, name, love, health):
super(Dog,self).__init__(name, love, health)
def eat(self):
print(self.name + '正在吃饭...')
class Pig(Dog):
def __init__(self, name, love, health):
super(Pig, self).__init__(name, love, health)
def showPig(self):
print('我的名字: '+self.name+'亲密度关系: ',self.love,'健康程度: ',self.health)
pig=Pig('Pig 猪',100,20)
pig.showPig()
# 打印为: 我的名字: Pig 猪亲密度关系: 100 健康程度: 20
继承特性之一:多继承
类同时继承多个父类,class C(A,B),
当有AB均有相同方法 ,而子类又重写时,调用子类
如果子类没有重写方法 , 优先继承左侧的类
class Pet:
def __init__(self,name,love,health):
self.name=name
self.love=love
self.health=health
def show(self):
print('宠物名: '+self.name+' 亲密度: ',self.love,'健康值: ',self.health)
class Dog(Pet):
def __init__(self, name, love, health):
super(Dog,self).__init__(name, love, health)
def show(self):
print(self.name + '正在吃饭...')
class animal:
def show(self):
print('我属于动物...')
class Pig(Dog,animal):
def __init__(self, name, love, health):
super(Pig, self).__init__(name, love, health)
# def show(self):
# print('我的名字: '+self.name+'亲密度关系: ',self.love,'健康程度: ',self.health)
pig=Pig('Pig 猪',100,20)
pig.show()
#当本身有调用对象则调用本身 如果没有则调用左侧的
# 本身有时打印为: 我的名字: Pig 猪亲密度关系: 100 健康程度: 20
#本身没有时打印为: Pig 猪正在吃饭... 优先调用左侧的
类名.mro(),可以看到所有父类,即搜索顺序
class Pet:
def __init__(self,name,love,health):
self.name=name
self.love=love
self.health=health
def show(self):
print('宠物名: '+self.name+' 亲密度: ',self.love,'健康值: ',self.health)
class Dog(Pet):
def __init__(self, name, love, health):
super(Dog,self).__init__(name, love, health)
def show(self):
print(self.name + '正在吃饭...')
class animal:
def show(self):
print('我属于动物...')
class Pig(Dog,animal):
def __init__(self, name, love, health):
super(Pig, self).__init__(name, love, health)
def show(self):
print('我的名字: '+self.name+'亲密度关系: ',self.love,'健康程度: ',self.health)
pig=Pig('Pig 猪',100,20)
print(Pig.mro())
#打印为:[<class '__main__.Pig'>, <class '__main__.Dog'>, <class '__main__.Pet'>, <class '__main__.animal'>, <class 'object'>]
鸭子类型:
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子.
单类模式:
该模式的主要目的是确保某一个类只有一个实例存在。
可以用id()看地址 当有属性时,需要在__new__()中也添加属性
#单例模式 : 实例==>对象==>内存地址==>同一块空间
# 资源共享的时候使用
class Myclass:
__school=None
def __new__(cls):
if cls.__school==None: #没有创建过
cls.__school=object.__new__(cls)
return cls.__school
else: #被创建过
return cls.__school
stu=Myclass()
stus=Myclass()
print(id(stu))
print(id(stus))
#打印为: 85660048
# 85660048