五、面向对象编程
1,类的定义
## 类名驼峰命名
## 类体中可以写任意Python代码,类体代码在定义时就运行
## __dic__ 可以查看类的命名空间
'''
{'__module__': '__main__', 'school': 'donghua', 'adress': 'shanghai', 'local': <classmethod(<function Student.local at 0x000001BCF418E9E0>)>, 'say_hello': <staticmethod(<function Student.say_hello at 0x000001BCF418EA70>)>, '__init__': <function Student.__init__ at 0x000001BCF418EB00>, 'say_score': <function Student.say_score at 0x000001BCF418EB90>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
'''
class Student:
# 类属性
# 可以被所有的实例对象所共享
school = 'donghua'
adress = 'shanghai'
stu_count = 0 # 统计注册的实例个数
# 类方法
@classmethod
def local(cls):
print(cls.adress)
# 静态方法
# 可以调用类的属性和方法
@staticmethod
def say_hello(str):
print(str)
Student.local()
# 通过构造函数__init__创建对象的属性
def __init__(self,name,age,score):
self.name = name
self.age = age
self.score = score
Student.stu_count += 1
# 创建实例对象方法
def say_score(self):
print(f'{
self.name}的分数是{
self.score}')
print(Student.say_score) ## <function Student.say_score at 0x00000255F6DDEB90>
s1 = Student('aini',22,80) ## 实例化
Student.say_score(s1) ## aini的分数是80
s1.say_score() ----- ## 本质是 Student.say_score(s1)
## 通过类名可以调用实例方法,需要传递实例进去
## 实例化发生的三件事情
1,先产生一个空对象
2,Python会自动调用 __init__方法
3,返回初始化完的对象
print(s1.__dict__) ------ ## ## {'name': 'aini', 'age': 22, 'score': 80}
2,封装
2.1 私有属性
## 在属性或方法前加__前缀,可以对外进行隐藏
## 这种隐藏对外不对内,因为__开头的属性会在类定义阶段检查语法时统一变形
class Foo:
__x = 1
def __test(self):
print('from test')
def f2(self):
print(self.__x) # 1
print(self.__test) ## <bound method Foo.__test of <__main__.Foo object at 0x000002063304B7F0>>
## 隐藏属性的访问
## Python不推荐此方法
print(Foo._Foo__x) ## 1
print(Foo._Foo__test) ## <function Foo.__test at 0x000001C42976E320>
## 这种变形操作只在检查类语法的时候发生一次,之后定义__定义的属性都不会变形
Foo.__y = 3
print(Foo.__y)
2.2 property使用
## 第一种类型
## 把函数像普通属性一样调用
class Person:
def __init__(self,name):
self.__name = name
@property
def get_name(self):
return self.__name
aini = Person('aini')
print(aini.get_name) ## 'aini'
## 第二种类型
class Person:
def __init__(self,name):
self.__name = name
def get_name(self):
return self.__name
def set_name(self,val):
if type(val) is not str:
print('必须传入str类型')
return
self.__name = val
## 伪装成数据接口的属性
name = property(get_name,set_name)
aini = Person('aini')
print(aini.name) ## 'aini'
aini.name = 'norah'
print(aini.name) ## 'norah'
## 第三种方法
## 起一个一样的函数名,用不同功能的property装饰
class Person:
def __init__(self,name):
self.__name = name
@property ## name = property(name)
def name(self):
return self.__name
@name.setter
def name(self,val):
if type(val) is not str:
print('必须传入str类型')
return
self.__name = val
@ name.deleter
def name(self):
print("不能删除")
3,继承
Python里支持多继承
python3里没有继承任何类的类都继承了Object类
Python2 里有经典类和新式类
经典类:没有继承Object ------------------ 新式类:继承了Object
class Parent1:
pass
class Parent2:
pass
class Sub1(Parent1): ## 单继承
pass
class Sub2(Parent1,Parent2): ## 多继承
pass
print(Sub1.__bases__) ## (<class '__main__.Parent1'>,)
print(Sub2.__bases__) ## (<class '__main__.Parent1'>, <class '__main__.Parent2'>)
3.1 继承的实现
class OldBoyPeople:
school = 'OLDBOY'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Student(OldBoyPeople):
def choose_course(self):
print(f'学生 {
self.name}正在选课')
class Teacher(OldBoyPeople):
def __init__(self,name,age,sex,salary,level):
# 调父类的属性就行
OldBoyPeople.__init__(self,name,age,sex)
self.salary = salary
self.level = level
def score(self):
print('老师 %s 正在给学生打分' %self.name)
t = Teacher('agen',25,'man',50000,'一级')
print(t.__dict__) ## {'name': 'agen', 'age': 25, 'sex': 'man', 'salary': 50000, 'level': '一级'}
stu_1 = Student('aini',22,'man')
print(stu_1.name,stu_1.age,stu_1.sex) ## aini 22 man
print(stu_1.school) ## OLDBOY
stu_1.choose_course() ## 学生 aini正在选课
3.2 单继承背景下的属性查找
class Foo:
def f1(self):
print('Foo.f1')
def

1553

被折叠的 条评论
为什么被折叠?



