91实例方法
类是摸具,方法是行为,是被所有对象共享的。
方法定义时要传参数
92类对象
class Student:
pass
print(id(Student))
Stu2=Student
print(id(Stu2))
s1=Stu2
print(id(s1))
地址一样,所以,可以调用。
print(id(Student))
Stu2=Student('hyh','18')
print(id(Stu2))
s1=Student('hyc','19')
print(id(s1))
如果赋值两个不同的对象,就会产生新的实例。地址就会不同。
所以类对象就是一个模板
93类属性
类的属性所有方法都能用,储存在类中,实例方法储存在类中,实例属性储存在实例中
内存结构
94 类方法和静态方法
类方法是从属于类对象的方法,通过格式
@classmethod
def 类方法名(cls[,形参列表])
函数体
静态方法和类方法形同,只是静态方法可以定义和类属性无关的方法。
重要:类方法和静态方法中,不能调用实例变量,实例方法。因为摸具建好了,实例对象不一定存在。
95_del_函数和垃圾回收
通过引用技术回收,由垃圾回收器调用del方法。
96_call_方法
定义了call方法的对象,可以向函数一样调用,
类比a+b本质上时a._add_(b)
那么,在使用数组a()时,相当于_call_()
97方法的重载(重复载入)
方法不能重名
方法的动态性,在生成的类可以从外向类中添加,修改方法。一切都是对象
定义方法中一定要加参数,方法的修改不带参数。
引用类时要有括号,有括号的话,下面的方法参数不传。
98私有属性,私有方法
两个下划线开头的属性,就成为私有属性
类的内部可以访问,外部不直接访问,可以通过_类名_私有属性名,类似图片,两个下划线不能被外部访问。
99私有方法
调用私有方法,需要加下划线,私有只在内部调用,
print(Employee._Employee__company) 这样可以输出
100@property装饰器
将@property放置在方法上,可以将方法变属性
将@方法.setter放在方法上,可以直接修该私有属性。
class Employee:
def __init__(self,name,salary): #属性
self.name=name
self.__salary=salary
@property #加上后就可以变成属性调用,相当于get
def salary(self):
return self.__salary
@salary.setter #通过setter方法代替构建新方法的方式修改
def salary(self,salary):
if 1000 < salary < 5000:
self.__salary = salary
else:
print('请输入正确工资')
'''#通过函数调用来将私有化对象公开
def get_salary(self):
return self.__salary
def set_salary(self,salary):
if 1000<salary<5000:
self.__salary=salary
else:
print('请输入正确工资')
emp1 = Employee('hyh', 1000) # 实验二
print(emp1.get_salary())
emp1.set_salary(2005) # 属性可以被修改
emp1.salary = 200000 #相当于开辟了一个新方法
print(emp1.salary)
print(emp1.get_salary())'''
emp1 = Employee('hyh', 1000)
print(emp1.salary) #加括号就是方法,不加就是属性
emp1.salary=2000
print(emp1.salary)
101面向对象三大特征
封装,继承,多态
102继承
class Person:
def __init__(self,name,age):
self.name=name
self.__age=age
def say_age(self):
print(self.name,'的年龄是',self.__age)
class Student(Person):
def __init__(self,name,age,score):
self.score=score
Person.__init__(self,name,age)
#构造函数中包含调用父类构造函数。根据需要,不是必须。子类并不会自动调用父类的__init__(),我们必须显示的调用它。
s=Student('hyh',12,50)
s.say_age()
print(s.name)
print(s._Person__age)
#通过继承person,S就可以直接调用person中的函数
103方法的重写
子类可以继承和改变父类方法
class Person:
def __init__(self,name,age):
self.name=name
self.__age=age
def say_age(self):
print('我的年龄是',self.__age)
def say_introduce(self):
print('我的名字是',self.name)
class Student(Person):
def __init__(self,name,age,score):
self.score=score
Person.__init__(self,name,age)
def say_introduce(self):
print('报告老师,我的名字是',self.name) #子类对父类已经重写
104object根类
通过类的方法mor()和类的属性_mor_可以输出这个类的层次结构,代码如下:
dir()函数可以查看可用属性
105重写_str_()方法
class Person:
def __init__(self,name):
self.name=name
def __str__(self): #重写字符串
return "名字是{0}".format(self.name)
p=Person('hyh')
print(p) #原本返回的是这个类的地址位置
106多重继承
一个子类可以有多个父类
107mor方法解析顺序
这个会输出bbb,先执行b
108super()获得父类定义
从结果看出,执行完都是执行的b类,通过a.say调用上一级和使用super.say调用都是相同的结果
109多态
#isinstance是判断类型函数,可以判断m是否是Man的已知类型。这样根据对象不同,调用不同的方法。就叫多态。
110特殊方法和运算符重载
就是将已有的运算符,比如+号进行设置,变得在类运算中有意义
x=p1+p2
TypeError: unsupported operand type(s) for +: 'Person' and 'Person'
运行结果:hyhhyc
111特殊属性
112对象的浅拷贝和深拷贝
需要导入copy模块
实验