面向对象2
绑定方法
1.给对象绑定,由对象调用
# 绑定给对象的方法,对象来调用,会把自己当成第一个参数传到函数里面self
class Student():
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def choose_coure(self, course):
pass
2.给类绑定的
class Student():
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
@classmethod
# 该方法绑定给类了,以后有类来调用,会自动把类名当成第一个参数传过来,cls
def from_conf(cls):
# cls:类名
pass
# 如果方法里,即需要类也需要对象,最好选择绑定给对象
def func(self):
print(self)
print(self.__class__)
' 使用@classmethod装饰的函数都是绑定给类的 '
非绑定方法
# 即不绑定给类的,也不绑定给对象的 叫做静态方法
class Student():
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
@staticmethod # 静态方法,不管是类还是对象来调用,都不会自动传递参数
def create_id():
import uuid
return uuid.uuid4()
隐藏属性
1.如何隐藏属性
class Student():
__school = 'xxx' # _类名__属性名 >>> _Student__school
def __init__(self,name,age):
self.__name = name
self.age = age
def __func(self): # _Student__func(self)
pass
"""
1.给属性前加__就隐藏了
2.隐藏对外不对内,外部要想使用,则在类内部开放可访问接口
( 可以更好的对外部严格控制 )
3.在类定义阶段发生了语法上的变形,此后再加__也不发生变形
为什么要隐藏: 类里面的隐藏属性, 类外部可以使用,但是目的不是让类外部使用的,类外部要是想用,在类内部开放接口进行访问
可以达到对外部数据的严格控制
"""
property装饰器
# 将方法伪装成属性
class Student():
__school = 'xxx' # _Student__school
def __init__(self,name,age):
self.__name = name
self.age = age
@property # 把get_name伪装成属性
def name(self):
return self.__name
@name.setter
def name(self):
pass
@name.deleter
def name(self):
pass
@name.deleter
def name(self):
pass
def set_name(self,v):
if not isinstance(v, str):
return
self.__name = v
面向对象的三大特征
1.封装
就相当于函数封装,使用更加简便
2.继承("重要喔")
1.什么是继承?
继承就是新建类的一种方式,新建的类我们称为子类或者派生类,被继承的类称为父类或基类。
子类可以使用父类中的属性或方法
2.为什么要继承?
类解决了对象与对象之间的代码冗余问题
继承则是为了解决类与类之间代码冗问题
3.如何使用继承?
新式类:继承了object类的子子孙孙都是新式类
经典类:没有继承object类的子子孙孙都是经典类
(只在python2中区分,python3中只有新式)
__base__查看父类
'继承是一把双刃剑,并不是越多越好'
3.多态
水:液态水,固态水,气态水
动物:人,猪,狗,猫 ...
继承
1.类的继承
# 父类,公共类
class People():
school = 'xxx'
def __init__(self,name,age,gender):
self.name = name
self.age = name
self.gender = gender
# 学生类
class Student(People):
def __init__(self,name,age,gender,course=None):
if course is None:
course = []
def choose_course(self, course):
self.courses.append(course)
print('%s 选课成功 %s' % (self.name, self.course))
# teacher类
class Teacher(People):
def __init__(self,name,age,gender,level):
self,level = level
People.__init__(self,name,age,gender)
def score(self, stu_obj, score):
stu_obj.score = score
print('%s给%s打了%s分' % (self.name,stu_obj.name,score))
单继承下属性查找
class Foo:
def f1(self):
print('from f1')
def f2(self):
print('from f2')
class Bar(Foo):
def f1(self):
print('from Bar.f1')
obj = Bar() # {}
obj.f1() # from Bar.f1
print(Foo.__base__) # 查看父类 <class 'object'>
多继承下属性查找
# 新式类:按照广度查询
# 经典类:按照深度查询
class A: # python3中就算不写(object) 直接加:也可直接使用,系统的底层会默认加上(object)
def test(self):
print('from A')
class B(A):
def test(self):
print('from B')
class C(A):
def test(self):
print('from C')
class D(B):
def test(self):
print('from D')
class E(C):
def test(self):
print('from E')
class F(D, E):
def test(self):
print('from F')
f1 = F()
f1.test() # from F
```
## super( )与mro列表
```python
super:
class People():
school = 'xxx'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
class Teacher(People):
def __init__(self,name,age,gender,level):
self.level = level
super().__init__(name,age,gender)
# 调用父类的方法,需要使用重复代码时调用
mro:
class A:
def test(self):
print('from A')
class B:
def test(self):
print('from B')
class C(A,B):
pass
c = C()
c.txt()
print(C.mro()) # 查看运行的顺序
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
多态与多态性 (了解即可)
# 抽象类,只能被继承,不能实例化
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod # 抽象法
def speak(self): pass
@abc.abstractmethod
def login(self): pass
class People(Animal):
def speak(self):
pass
def login(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼')
class Dog(Animal):
def speak(self):
print('汪汪')
obj = People()
obj.speak()
# 多态练习
class Pig():
def speak(self):
print('哼哼')
class Dog():
def speak(self):
print('汪汪')
class People():
def speak(self):
print('hello world!')
obj = People()
obj1 = Pig()
obj2 = Dog()
# 多态特性:在不用考虑对象数据的情况下,直接调用函数
def animal(animal):
return animal.speak()
animal(obj)
animal(obj1)
animal(obj2)
# 父类限制子类办法
class Animal():
def speak(self):
raise Exception("实现speak方法")
解决类与类之间代码冗余的问题:1.继承, 2 组合
class People():
school = 'xxx'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Admin(People):
pass
class Course():
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price
python = Course('python', '6mon', 10000)
linux = Course('linux', '6mon', 15000)
class Student(People, Course):
def __init__(self, name, age, gender, course=None):
if course is None:
course = []
self.course = course
super().__init__(name, age, gender)
def choose_course(self, stu_obj, course):
stu_obj.courses.append(course)
obj = Student('lili', 18, 'male')
obj.course.append(linux)
print(obj.name)
print(obj.__dict__)
for i in obj.course:
print(i.__dict__)
内置函数
1.__init__
2.__str__
3.__del__
4.__ender__
5.__exit__
6.__call__
class Scripts():
school = 'xxx'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
self.f = open('a.txt', 'w]')
def tell(self):
print('name:%s,age:%s,gender:%s' % (self.name, self.age, self.gender))
# 返回值只能是字符串
def __str__(self):
return ('name:%s' % self.name)
# 手动执行del,程序执行完毕后再执行
def __del__(self):
print('__del__')
self.f.close()
# 对象加括号自动触发
def __call__(self, *args, **kwargs):
print('__call__')
stu = Scripts('ko', 18, 'male')
# __enter__ __exit__
class Open:
def __init__(self, name):
self.name = name
def __enter__(self):
print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
return self
# return 123
def __exit__(self, exc_type, exc_val, exc_tb):
print('with中代码块执行完毕时执行我啊')
with Open('a.txt') as f:
print('=====>执行代码块')
print(f)
print(f, f.name)
class Student():
school = 'sh'
def __init__(self, name, age):
self.name = name
self.age = age
def func(self):
print('from func')
stu = Student('ly', 18)
# 1. getattr
print(getattr(stu, 'school', None)) # 对象 则返回值,None可以不写,如果没有该内容则返回None
stu.func()
print(getattr(stu, 'func')) # 方法 返回内存地址,加()调用
getattr(stu, 'func')() # 必须掌握
#2. setattr 在后增加内容
setattr(stu, 'x', 123)
print(stu.__dict__)
#3. hasattr 判断是否存在
print(hasattr(stu, 'name'))
#4. delattr 除去内容
delattr(stu, 'name')
print(stu.__dict__)