"""
类
class 类名():#()可不写
pass#定义在类中的函数称方法
对象名=类名()
一个类可创建多个对象
继承 一个子类可以继承多个父类;一个父类也可以拥有多个子类;若一个类没有继承任何类,哪默认继承object类
class 类名(父类1,父类2...,父类n)
pass
方法重写 父类方法不能适用子类需求时,子类可以重写父类方法
重写时,方法名称必须和父类方法名称相同,若需要父类的内容,可通过super().方法()调用父类中的方法
多态
不管对象数据类型,不管类之间是否有继承关系,只看对象的方法。只有有同名方法,就可实现多态
object类 所有类的父类,都有object类的属性和方法
__new__() 由系统调用,用于创建对象
__init__() 创建对象时手动调用,用于初始化对象属性值
__str__() 对象的描述,返回值是str,默认输出对象的内存地址
特殊方法
__add__() +
__sub__() -
__mul__() *
__truediv__() /
__mod__() %
__floordiv__() //
__pow__() **
__lt__() <
__le__() <=
__eq__() ==
__gt__() >
__ge__() >=
__ne__() !=
特殊属性
obj.dict__ 对象属性字典
obj.__class__ 对象所属类
class.__bases__ 类的父类元组
class.__base__ 类的父类,如果继承多个父类,只显示第一个父类
class.__mro__ 类的层次结果
class.__subclasses__ 类的子类列表
"""
import copy#拷贝库
class Person:
character='thinking'#类属性直接定义在类中,方法外的变量
def __init__(self,gender,age,skin,fcontinent):#实例属性定义在__init__方法中,自带self参数
print('创建成功')#__init__方法中可有函数体,不能递归,__init__定义时,返回值为None
self.gender=gender#实例属性赋值
self.age=age#无_是普通实例属性,类的内部,外部,及子类都可以访问
self._skin=skin#_指是受保护的,只能本类和子类访问
self.__fcontinent=fcontinent#__指是私有的,只能类本身去访问
@property#可使用@property修饰,将方法转为属性使用,只能查看,不能修改
def fcontinent(self):
return self.__fcontinent
@fcontinent.setter #对应方法.setter 尝试修改@property对应修饰的方法→属性
def fcontinent(self,where):
if where!='Asia' and where!='Africa' and where!='Europe' and where!='North America' and where!='South America':
print("fcontinent有误,已默认设置为Asia")
self.__fcontinent ='Asia'
else:
self.__fcontinent=where
def show0(self):#实例方法定义在类的函数中,自带self参数 无_是普通的实例方法
return f'I`m an {self.age}-year-old {self.gender}'#实例方法使用实例属性
def _show1(self):#_指受保护的实例方法,子类及其本身可以访问
return f'I`m {self._skin} race'
def __show2(self):#__指私有的实例方法,只有定义的类可以访问
return f'I`m form {self.__fcontinent}'
@staticmethod#静态方法用@staticmethod修饰,不能调用实例属性和实例方法
def static():
return "death"
@classmethod#类方法用@classmethod修饰,不能调用实例属性和实例方法
def kind(cls):#自带cls参数
return "animal"
def __str__(self): # 重写__str__方法
return 'person类 有gender,age,skin,fcontinent四个实例属性'
man0=Person('man',18,'yellow','Asia')#自带参数无需手动输入
print(Person.character,man0.character)#类属性直接使用类名打点或对象名打点调用
print(man0.gender,man0.age,man0._skin)#普通实例属性对象名打点调用,受保护属性对象名打点下划线调用
#print(man0.__fcontinent)#超出class定义范围
print(man0._Person__fcontinent)#私有属性范围外的调用,无@property修饰
print(man0.fcontinent)#私有属性范围外的调用,有@property修饰
#man0.fcontinent='North America'#只能查看,不能修改 property 'fcontinent' of 'Person' object has no setter
man0.fcontinent='其他'#调用有方法.setter修饰方法修改@property对应修饰的方法→属性
print(man0.fcontinent)
man0.fcontinent='North America'
print(man0.fcontinent)
print(man0.show0())#实例属性使用对象名打点调用
print(man0._show1())
#print(man0.__show())#超范围
print(man0._Person__show2())#私有方法范围外的调用
print(Person.static())#静态方法直接使用类名打点调用
print(Person.kind())#类方法直接使用类名打点调用
print(dir(man0))#dir() 返回一个包含对象的所有属性和方法名称的字符串列表
print(man0)#对象名自动调用__str__方法
print(man0.__str__())#手动调用
man0.quality='brave'#对象动态绑定属性,打点直接赋值
man0.age=20#对象动态修改属性
man0._skin='white'
man0._Person__fcontinent='Asia'
print(man0.gender,man0.age,man0._skin,man0._Person__fcontinent,man0.quality)
def introduce():#动态绑定方法
return man0.show0()+ " and i`m "+man0.quality
man0.introduce=introduce#对象赋值
print(man0.introduce())#对象打点调用
class Student(Person):
def __init__(self,gender,age,skin,fcontinent,school):
super().__init__(gender,age,skin,fcontinent)#调用父类的部分初始化方法
self.school=school
def show0(self):#方法重写
father=super().show0()#调用父类
print(f'{father} study at {self.school}')
student0=Student('man',10,'yello','Asia','Hope Primary School')
student0.show0()
print(student0._show1())
print(student0._Person__show2())
class Doctor(Person):
def __init__(self,gender,age,skin,fcontinent,hospital):
super().__init__(gender, age, skin, fcontinent)
self.hospital=hospital
def show0(self):#子类重写
return f'I`m an {self.age}-year-old {self.gender} working at {self.hospital}'
doctor0=Doctor('man',80,'yello','Asia','the People`s Hospital')
print(doctor0.show0())
class FatherA:
def __init__(self,A):
self.A=A
def showA(self):
return "showA"
class FatherB:
def __init__(self,B):
self.B=B
def showB(self):
return "showB"
class Son(FatherA,FatherB):#不可创建一致类,父类间不能是父子关系
def __init__(self,A,B,C):
FatherA.__init__(self,A)#有多个父类,不能用super()
FatherB.__init__(self,B)
self.C=C
son=Son('a','b','c')
print(son.showA())
print(son.showB())
class A:
def output(self):
print("A")
class B:
def output(self):
print("B")
class C:
def output(self):
print("C")
def output(item):
item.output()#多态 不管对象数据类型,不管是否有继承关系,只看对象是否具有同名方法
A=A()
B=B()
C=C()
output(A)
output(B)
output(C)
a,b=10,20
print(a.__add__(b))
print(a.__sub__(b))
print(a.__mul__(b))
print(a.__truediv__(b))
print(a.__mod__(b))
print(a.__floordiv__(b))
print(a.__pow__(b))
print(a.__lt__(b),a.__le__(b),a.__eq__(b),a.__gt__(b),a.__ge__(b),a.__ne__(b))
print(man0.__dict__)
print(A.__dict__)
print(man0.__class__,type(man0))
print(Person.__bases__)
print(Son.__bases__)
print(Person.__base__)
print(Son.__base__)
print(Person.__mro__)
print(Son.__mro__)
print(Person.__subclasses__())
print(Student.__subclasses__())
class Number:
def __init__(self,real,plural):
self.real=real
self.plural=plural
class Real:
pass
class Plural:
pass
real=Real()
plural=Plural()
number0=Number(real, plural)
number1=number0#变量(对象)的赋值是地址赋值,不创建新对象,两个变量名指向同一个对象
print(number0,number0.real,number0.plural)
print(number1,number1.real,number1.plural)
number2=copy.copy(number1)#变量(对象)的浅拷贝,创建新对象,但子对象内容不拷贝,使用同一个子对象
print(number2,number2.real,number2.plural)
number3=copy.deepcopy(number1)#变量(对象)的深拷贝,创建新对象,新子对象
print(number3,number3.real,number3.plural)
运行结果