Python皆对象。
一、封装(提高数据安全性)
将数据(属性)和行为(方法)包装到类对象中,该属性不希望在外部类对象访问,前面使用两个"__"(下划线)。
class Teacher:
def __init__(self,name,age):
self.name = name
self.__age = age
def show(self):
print(self.name,self.__age)
stu1 = Teacher('李四',52)
print(stu1.__age)#外部无法访问封装对象
print(stu1._Teacher__age)#可以强制访问封装对象
【注】可以强制访问,使用(stu1._Teacher__age )。不建议使用
二、继承
class 子类名(父类1,父类2........):
pass
1.如果一个类没有继承父类,则默认继承object(所有类的父类)。
2.可以多继承。
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(self.name,self.age,self.score)
class Student(Person):#继承Person类
def __init__(self,name,age,score):
super().__init__(name,age)#继承Person类中__init__()方法
self.score = score
def info1(self):
print(self.name,self.age,self.score)
class Teacher(Person):#继承Person类
def __init__(self,name,age,teacherofyear):
super().__init__(name,age)#继承Person类中__init__()方法
self.teacherofyear = teacherofyear#重写__init__()方法
def info2(self):
print(self.name,self.age,self.teacherofyear)
stu1 = Student('C罗',37,100)
tea = Teacher('梅西',36,5)
stu1.info1()
tea.info2()
C罗 37 100
梅西 36 5
三、方法重写
对父类的方法不满意,可以在子类中改写父类中的方法。
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, score):
super().__init__(name, age)
self.score = score
# def info1(self):
# print(self.name, self.age, self.score)
def info(self):#于以上两行代码意思相同
super().info()
print(self.score)
class Teacher(Person):
def __init__(self, name, age, teacherofyear):
super().__init__(name, age)
self.teacherofyear = teacherofyear
# def info2(self):
# print(self.name, self.age, self.teacherofyear)
def info(self):#于以上两行代码意思相同;重写Person类中info()函数
super().info()
print(self.teacherofyear)
stu1 = Student('C罗', 37, 100)
tea = Teacher('梅西', 36, 10)
C罗 37 100
梅西 36 10
四、object 类
1.内置函数dir( )可查看指定对象所有属性。
2.重写__str__方法后print(stu);stu:是实例对象;相当于调用__str__方法。
class Student():#默认继承object类
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return '我是{0},今年{1}岁'.format(self.name,self.age)
stu = Student('C罗',38)
print(dir(stu))
#print(stu)#没有重写__str__方法前<__main__.Student object at 0x0000021271165580>
print(stu)#重写__str__方法后
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
我是C罗,今年38岁
五、多态的实现
多态“就是有多种形态”,即使不知道一个变量所引用的类型(object/Person/Animal等)动态决定那个对象的方法。
1.静态语言实现多态的三个条件:继承;方法重写;父类引用指向子类;(JAVA语言)
2.动态语言(Python语言):不关心对象是什么类型(object/Person/Animal等),只关心对象的行为。(例:因为看它走起来像一只小毛猫,所以我们就认定它就是一只小猫。)
class Animal(object):
def eat(self):
print('动物都要吃饭!')
class Dog(Animal):
def eat(self):
print('小狗爱吃骨头')
class Cat(Animal):
def eat(self):
print('猫喜欢吃鱼')
class Person:
print('人要吃五谷杂粮!')
六、特殊属性
1. __dict__:获取类对象或实例对象所绑定的所有属性和方法字典。
2.__class__:获取对象所属类。
3.__bases__:输出父类。
4.__base__:输出最近的父类(积类),第一位置参数;
5.__mro__:父类的层次结构。
6.__subclasses__():查看子类;
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name,age):
self.name = name
self.age = age
class D(A):
pass
x = C('Python',15)#实例对象
print(x.__dict__)
print(C.__dict__)
print(x.__class__)
print(C.__bases__)
print(C.__base__)
print(C.__mro__)
print(A.__subclasses__())
{'name': 'Python', 'age': 15}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x000001A99106E3A0>, '__doc__': None}
<class '__main__.C'>
(<class '__main__.A'>, <class '__main__.B'>)
<class '__main__.A'>#第一个参数
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
[<class '__main__.C'>, <class '__main__.D'>]
七、特殊方法
1.__len__():重写__len__()方法,让内置函数len()的参数可以是自定义。
2.__add__():可以自定义对象具有“+”功能。
a = 2
b = 3
c = a+b
print(c)
print(a.__add__(b))
class Stuednt:
def __init__(self,name):
self.name = name
def __add__(self, other):
return self.name+other.name
def __len__(self):
return len(self.name)
stu1 = Stuednt('李四')
stu2 = Stuednt('java')
s = stu1 + stu2 #def __add__(self, other)方法重写
print(s)
s = stu1.__add__(stu2)
print(s)
lst = [45,65,85,85,92,100]
print(len(lst))
print(lst.__len__())
print(stu1.__len__()) #返回字符数
print(len(stu2))#def __len__(self)方法重写
5
5
李四java
李四java
6
6
2
4
3.__new__():用于创建对象、分配空间。
4.__init__():对创建对象进行初始化。
class Person: #默认obje类
def __new__(cls, *args, **kwargs):
print('__new__被调用了,cls的id值位{0}'.format(id(cls)))#8606
obj = super().__new__(cls)#重写__new__方法
print('创建的对象的id时:{0}'.format(id(obj)))#2128
return obj
def __init__(self,name,age):
print('__init__被调用了,self的id值位{0}'.format(id(self)))#2128
self.name = name
self.age = age
print('object这个类对象的id:{0}'.format(id(object)))#5360
print('Person这个类对象的id:{0}'.format(id(Person)))#8606
#创建Person类的实例对象
p1 = Person('李四',25)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1)))#2128
object这个类对象的id:140708392385360
Person这个类对象的id:1827788328608
__new__被调用了,cls的id值位1827788328608
创建的对象的id时:1827794192128
__init__被调用了,self的id值位1827794192128
p1这个Person类的实例对象的id:1827794192128
【注】上图片从创建—>初始化流程。
八、赋值
class Cpu:
pass
cpu1 = Cpu()
cpu2 = cpu1
print(id(cpu1))#9360
print(id(cpu2))#9360
9360
9360
九、浅拷贝
Python拷贝一般都是浅拷贝,对象包含的子对象内容不拷贝,因此源对象与拷贝对象会引用同一个子对象。
computer1 = copy.copy(computer)
class Cpu:
pass
class Disk:
pass
class Computer:#源对象 浅拷贝值拷贝源对象;
def __init__(self,cpu,disk):
self.cpu = cpu
self.disk = disk
cpu1 = Cpu()
# print(cpu1)
disk = Disk()
computer = Computer(cpu1,disk)
import copy
computer1 = copy.copy(computer)
print(computer,computer.cpu,computer.disk)
print(computer1,computer1.cpu,computer1.disk)
<__main__.Computer object at 0x00000263AA283B50> <__main__.Cpu object at 0x00000263AA255A60> <__main__.Disk object at 0x00000263AA283BB0>
<__main__.Computer object at 0x00000263AA290190> <__main__.Cpu object at 0x00000263AA255A60> <__main__.Disk object at 0x00000263AA283BB0>
【注】cpu与disk 实例对象的id相同。
十、深拷贝
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象与拷贝对象所有子对象也不相同。
computer2 = copy.deepcopy(computer)
class Cpu:
pass
class Disk:
pass
class Computer:#源对象 浅拷贝值拷贝源对象;
def __init__(self,cpu,disk):
self.cpu = cpu
self.disk = disk
cpu1 = Cpu()
# print(cpu1)
disk = Disk()
computer = Computer(cpu1,disk)
import copy
computer2 = copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)
<__main__.Computer object at 0x0000020F0C693B50> <__main__.Cpu object at 0x0000020F0C665A60> <__main__.Disk object at 0x0000020F0C693BB0>
<__main__.Computer object at 0x0000020F0C6A0430> <__main__.Cpu object at 0x0000020F0C6A0820> <__main__.Disk object at 0x0000020F0C6DA640>
【注】cpu与disk 实例对象的id不相同。
有什么疑问可以私信我,也可以一起交流学习。
^0^