昨日内容回顾
面向过程
# 核心和过程二字, 先干什么,在干什么,最后干什么
他是一种思想
# 优点:复杂的问题简单化,进而流程化
# 缺点:扩展性差
# 应用场景:对扩展性要求不高的地方
面向过程和面向对象没有谁好谁坏
面向对象
# 核心是对象二字,
1. 程序中:
就是盛放数据属性和功能的容器
2. 现实中:
特征与技能的结合体
# 优点: 扩展性强,维护性强
# 缺点:编程复杂度高
# 应用场景:对扩展性要求较高的地方
类的定义和对象的产生
"""
驼峰命名:大驼峰,小驼峰
大驼峰:UserName => 类名推荐使用
小驼峰:userName
下划线的命名:user_name 除类名之外推荐使用
类名的命名:大驼峰
class 类名():
pass
是先有类还是先有对象?
1. 现实中:
先有对象,在有类
2. 在程序中:
必须要先定义类,在调用类产生对象
"""
# 定义类
class Student():
school = ‘SH‘
def choose_course(stu_obj, course):
pass
print(123)
"""
定义类发生了几件事?
1. 立即执行类体代码,
2. 产生一个类的名称空间,把类体中的属性名和函数名都扔到一个大字典中
3. 把类的名称空间绑定给__dict__ (类名.__dict__)
"""
# Student.school
#
如何查看类的名称空间
# Student.__dict__
# 如何调用类?类名()
stu1 = Student() # 由Student类产生的对象 Object 空对象
stu2 = Student() # 由Student类产生的对象 Object 空对象
stu3 = Student() # 由Student类产生的对象 Object 空对象
stu1 = {‘name‘:‘egon‘, ‘age‘:18}
定制对象自己独有的属性
class Student():
school = ‘SH‘
# 初始化方法,__init__名字一定不能改,__开头的方法都称为魔术方法, 简称魔法
##############调用类的时候自动触发的方法###########################
def __init__(self, name, age, gender):\ # stu_obj = stu1 => {‘k‘:‘v‘}
# name => name形参
self.name = name
self.age = age
self.gender = gender
stu = Student(‘egon‘, 18, ‘male‘) # stu = Student(stu, ‘egon‘, 18, ‘male‘)
stu1 = Student(‘egon1‘, 19, ‘female‘) # stu = Student(stu, ‘egon‘, 18, ‘male‘)
print(stu) # {‘name‘:‘‘, ‘age‘:‘‘, ‘gender‘:‘‘}
print(stu1) # {‘name‘:‘‘, ‘age‘:‘‘, ‘gender‘:‘‘}
属性的查找
class Student():
school = ‘SH‘
# 初始化方法,__init__名字一定不能改,__开头的方法都称为魔术方法, 简称魔法
##############调用类的时候自动触发的方法###########################
def __init__(self, name, age, gender):\ # stu_obj = stu1 => {‘k‘:‘v‘} {‘name11111‘}
# name => name形参
self.name = name
self.age = age
self.gender = gender
def func(self):
pass
# 1. 类属性的查找
# 查找属性
Student.school
# 增加
Student.x = ‘xxx‘
# 修改
Student.school = ‘yyy‘
# 删除
del Student.school
# 方法的调用
# 默认情况方法是给对象用的
Student.func(stu)
#################对象属性的查找#################################
stu = Student()
# 查找属性
stu.school
# 增加
stu.x = ‘xxx‘
# 修改
stu.school = ‘yyy‘
# 删除
del stu.school
#################对象方法的查找#################################
stu.func() # stu.func(stu) 对象调用方法,第一个参数不用传递
######################补充##############################
调用类的过程也是实例化的过程,得到的结果就叫一个实例
今日内容详细
- 面向对象的小案例
- 绑定方法
- 非绑定方法
- 如何隐藏属性
- property装饰器
面向对象的小案例
题目:
定义一个类,产生一堆对象
要求:
要有一个计数器,记录一共差生了多少个对象
class Student():
count = 0
# {‘count‘:0}
# {‘count‘:1}
# {‘count‘:2}
# {‘count‘:3}
def __init__(self, name, age):
# self => obj => {‘name‘:‘egon‘, ‘count‘:1}
# self => obj1 => {‘name‘:‘egon1‘, ‘count‘:1}
self.name = name
self.age = age
self.count += 1--------------------------①
Student.count += 1-----------------------②
# print(self.__class__) 和 print(Student) #对象中如何拿到类*
# <class ‘__main__.Student‘> 结果一致
obj = Student(‘egon‘, 18)
obj1 = Student(‘egon1‘, 18)
obj2 = Student(‘egon2‘, 18)
print(obj.count)
print(obj1.count)
print(obj2.count)
①的结果是1, ②的结果是3
注:类中的属性修改会直接影响到对象的调用,类中的属性一改全改
题目:定义两个英雄类
1. 每个英雄都要有昵称, 生命值,攻击力
2. 实例化出两个对象
3. 两个英雄互相殴打,掉血。
绑定方法
# 绑定方法分为两种:
1. 绑定给对象的 # 就是让对象来调用的
2. 绑定给类的 # 就是让类来调用的
# 1. 绑定给对象的
# 初始化
class Student():
school = ‘SH‘
def __init__(self, name, age):
self.name = name
self.age = age
# 在类中书写方法,默认绑定给对象使用的
def tell_info(self):
print("%s-%s" % (self.name, self.age))
def func(self):
print("func")
实例化(调用类的过程)
obj = Student(‘egon‘, 18)
obj.tell_info()
# 对象调用方法,默认绑定对象,直接把对象本身直接传给self,第一个参数不用传递
obj.func()
# 2.绑定给类的方法
# setting.py文件
# IP = ‘127.0.0.1‘
# PORT = ‘3306‘
import settings
class Mysql:
school = ‘SH‘
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod # 意味着该方法绑定给类了,类来调用,会把类型当成第一个参数传过来
def func(cls):
# class_name => Mysql
print(cls)
return cls(settings.IP, settings.PORT)
# return self.__class__(settings.IP, settings.PORT) # 动态
# return Oracle(settings.IP, settings.PORT)
obj = Mysql(settings.IP, settings.PORT)
"""
总结:
1. 绑定给对象的
对象来调用,把对象自己当成第一个参数传递
2. 绑定给类的方法
@classmethod
类来调用,把类名当成第一个参数传递
"""
非绑定方法
"""
非绑定方法:即不绑定给对象,也不绑定给类
"""
# import uuid #快速生成随机数
# print(uuid.uuid4())
class Test():
def __init__(self, name, age):
self.name = name
self.age = age
self.id = self.create_id()
@staticmethod # 静态方法
def create_id():
import uuid
return uuid.uuid4()
obj = Test(‘egon‘, 18)
print(obj.id)
# 用类调用
# print(Test.create_id())
# 用对象调用
print(obj.create_id())
隐藏属性
class Student():
__school = ‘SH‘ # _Student__school
# school = ‘SH‘ # _Student__school
def __init__(self, name):
self.__name = name # self._Student__name
def func(self):
print(‘func‘)
def get_school(self):
return self.__school # self._Student__school
# stu=Student()
# print(Student.__dict__) #查看类的名称空间
# print(Student.__Student__school) #同上
class Student():
__school = ‘SH‘ # _Student__school
# school = ‘SH‘ # _Student__school
def __init__(self, name):
self.__name = name # self._Student__name
def __func(self): # _Student__func
print(‘func‘)
def get_school(self):
return self.__school # self._Student__school
def set_school(self, v):
if type(v) is not str:
return
self.__school = v
def get_func(self):
return self.__func()
"""
**隐藏属性特点**:
1. 在类定义阶段发生了变形: _类名__属性名
2. 对内不对外,内部照样获取,外部拿不到
为什么要隐藏:
对内部的属性或者方法做隐藏,可以更好的限制外部使用者, 要想让外部访问,在类内部定义对外可访问的接口。
"""
property装饰器
"""
property装饰器: 就是将函数功能封装成数据属性
"""
class Student():
__school = ‘SH‘ # _Student__school
__name = ‘egon‘
def __init__(self, name):
self.__name = name # self._Student__name
def __func(self): # _Student__func
print(‘func‘)
# @property # 这个函数已经变成了属性
# def get_name(self):
# return self.__name # self._Student__school @property # 这个函数已经变成了属性
def name(self):
return self.__name # self._Student__school
@name.setter
def name(self, v):
self.__name = v
@name.deleter
def name(self):
print("不让删除")
了解内容:
class Student():
__name = ‘egon‘
def get_name(self):
return self.__name # self._Student__school
def set_name(self, v):
self.__name = v
def del222_name(self):
print("不让删除")
# property中的参数必须按照这个顺序
xxxx = property(get_name,set_name,del222_name)
obj = Student()
print(obj.xxxx)
obj.xxxx = ‘x‘
print(obj.xxxx)
面向对象编程(下)