面向对象编程

面向对象编程

面向过程的概念

面向过程核心即过程二字,解决问题的流程,即先干什么,在干什么,最后干什么

# 例如:
1.洗衣服
2.把大象放进冰箱需要几步?
"""
	1.把冰箱门打开
	2.把大象大象放进去
	3.关上冰箱门
"""
3.流水线生产饮料

优点:复杂的问题流程化,进而简单化
缺点:牵一发而动全身,扩展性差,可维护性差
应用场景:对扩展性要求不高的地方,eg:安装包的使用

# 注册的功能
"""
	1.用户输入用户名和密码
	2.验证参数
	3.写入文件,注册成功
"""

面向对象的概率

面向对象核心即对象二字

什么是对象?

	1.程序中:
		函数:盛放数据的容器
		对象:盛放数据和函数的容器
	2.现实生活中:
		一切皆对象
		对象:特征与技能的结合体
优点:扩展性强,可维护性强
缺点:编程难度高
应用场景:对扩展性要求较高的地方 eg:微信,qq

# 举例:
	以学生选课系统为例
# 版本三
def choose_course(stu_dict,course):
    stu_dict['course'].append(course)
    print('%s选课成功 %s'%(stu_dict['name'],stu_dict['course']))

stu1 ={
    'name':'jason',
    'age':'15',
    'gender':'male',
    'course':[],
    'choose_course':choose_course}

stu2 ={
    'name':'ly',
    'age':'18',
    'gender':'male',
    'course':[],
    'choose_course':choose_course}

stu1['choose_course'](stu1,'python')  # jason选课成功 ['python']
stu2['choose_course'](stu2,'python')  # ly选课成功 ['python']

类的定义和对象的产生

对象:特征与技能的结合体
类:一系列对象相似的特征与相似的技能的结合体

强调:站在不同的分类,划分的分类不一定一样

# 问题来了:
	到底是先有类还是先有对象?
	1.程序中:
		必须先定义类,然后调用类产生对象
        2.现实生活中:
                先有对象,再有人类

"""
使用专业的语法定义类:
    1.定义函数:
        def 函数名():
            pass
    2.定义类:
        class 类名():
            pass
"""

定义类:
"""
    发生了什么事?
        1.立即执行类体代码
        2.产生一个类的名称空间,把类体里面执行的名字都扔到名称空间中(大字典)
        3.把类的名称空间绑定给__dict__,类名.__dict__
"""
# 类名一般情况下首字母都大写
class Student():
    # 定义一个属性
    school = 'SH'

    # 定义一个技能(函数)
    def choose_course(stu_dict,course):
        stu_dict['course'].append(course)
        print('%s选课成功 %s' % (stu_dict['name'],stu_dict['course']))

# 查看类的名称空间
print(Student.__dict__)

# 产生对象
#调用类产生对象,默认产生的是一个空对象{}

stu1 = Student()
stu2 = Student()
stu3 = Student()

print(stu1.__dict__)
print(stu2.__dict__)
print(stu3.__dict__)

对对象定制自己独有的属性

class Student():
  # 定义一个属性
  school = 'SH'
  # 初始化方法
  # 调用类自动触发的函数
  # 该方法不是一定要定义,需要用到就定义,不需要可以不定义
  def __init__(stu_obj,name,age,gender):
  # 空对象.name = name
  # 空对象.age = age
  # 空对象.gender = gender
  stu_obj.name = name # stu1.__dict__['name'] = 'jason' 
  stu_obj.age = age # stu1.__dict__['age'] = 18
  stu_obj.gender = gender # stu1.__dict__['gender'] = 'male'
  # return None # 这个方法中不能有返回值
# 定义一个技能(函数)
def choose_course(stu_dict,course):
    stu_dict['course'].append(course)
    print('%s选课成功 %s' % (stu_dict['name'],stu_dict['course']))

# 调用类发生了几件事?
"""
  1.得到一个空对象
  2.调用了Student.__dict__(空对象,'ly',18,'male')
  3.得到一个初始化结果
"""
stu1 = Student('ly',18,'male')
stu2 = Student('jason',18,'male')
# stu1 = Student()
# print(stu1.__dict__)
# print(stu2.__dict__)

# print(stu1.name)
# print(stu2.name)

# 属性的查找:先从自己的对象中查找,然后再去产生对象的类中寻找

stu1.school = 'aaaa' # 在stu1名称空间产生一个school = aaaa
print(stu1.school)

属性的查找顺序

class Student():
    # 定义一个属性
    school = 'SH'

    def __init__(self,name,age,gender,course=None)
        if course is None:
            course = []
        self.name = name # stu1.__dict__['name'] = 'jason'
        self.age = age  # stu1.__dict__['age']  = 18
        self.gender = gender  # stu1.__dict__['gender']  = 'male'
        self.course =course
    def choose_course(self,course)
    # stu_dict => stu
    self.course.append(course)
    print('%s选课成功 %s' % (self.name,self.course))

   def func(self,name,age):
       pass
# 属性的查找:
# 1.类属性: 在类中写的属性就称之为类属性
# 2.对象属性: 在对象自己的名称空间中的属性就是对象属性

# 类属性的查找
# 1.查
# print(Student.school)

# 2.增加
# Student.country = 'China'

# 3.改
Student.school = 'BJ'

# 4.删除
del Student.school
print(Student.__dict__)
{}
stu = Student('ly',18,'male')  # 实例化对象:stu就是一个实例

# 对象属性
# 1.查
# print(stu.name)
# print(stu.age)
# print(stu.gender)

# 2.增
# stu.aaa = 'aaa'

# 改
# stu.name = 'zzy'

# 4.删除
# del stu.name
# print(syu.__dict__)


# 类中的方法,类可以调用,对象也可以调用
# 类调用方法
# Student.choose_course(stu,'python') # 类来调用,函数的参数有几个就要传几个
print(Student.choose_course)

# 对象的调用方法
# 类中的方法,类可以调用,对象也可以调用,但是,推荐对象来调用,因为对象来调用,会把自己当做第一个参数传递给函数
stu.choose_course('python') # stu.choose_course(stu,'python')

class Teacher():
    pass
print(isinstance(123,int))  # True
print(isinstance(syt,Teacher))  # Flase

小练习案例

题目:
    1.定义一个类,产生一堆对象
    
    2.统计产生了多少个对象
      """思路:定义一个计数器,每产生一个对象,计数器加1"""


class Student():
  school = 'SH'
  count = 0  # 专门用来计数

def __init__(self,name,age):
    # self => stu => {'name':'ly','age':18,'count':1} 
    # self => stu1 => {'name':'ly1','age':18,'count':1}
    # self => stu2 => {'name':'ly2','age':18,'count':1}
    self.name = name
    self.age = age
    # self.count = count +=1
    # Student.count += 1
    # self.__class__ # Student
    self.__class__.count += 1

绑定方法

绑定方法分为2种
    1.绑定给对象的
        class Student():
            def __init__(self,name,age,gender):
                self.name = name
                self.age = age
                self.gender = gender

# 绑定给对象的方法,对象来调用.会把自己当做第一个参数传到函数里面self                
            def tell_info(self):
                print('name:%s,age:%s,gender:%s'%(self.name,self.age,self.gender))

            stu = Student('ly',18,'male')
            # print(stu.name)
            stu.tell_info() # stu.tell_info(stu)

     2.绑定给类的 
        class Mysql():
            def __init__(self,ip,port)
                self.ip = ip
                self.port = port

        @classmethod  # 该方法绑定给类了,以后有类来调用,会自动把类名当做第一个参数传过来,cls
        def form_conf(cls)
            # cls => Mysql
            # obj = Mysql(settings.IP,settings.PORT)
            obj = cls(settings.IP,settings.PORT)
            return obj
Mysql.from_conf()        `        

非绑定方法

# 既不绑定类,也不绑定对象
class Student():
    school = 'SH'
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @staticmethod # 静态方法
    def create_id():
        import uuid
        return uuid.uuid4()

stu = Student('ly',18)
print(stu.create_id())

如何隐藏属性

# 1.如何隐藏
"""
    1.在类定义阶段,发生了语法上的变形_类名__属性名
    2.隐藏对外不对内
    3.只有在类定义阶段发生变形,其他情况都不发生变形

为什么要隐藏:类里面的隐藏属性,类外部可以使用,但是目的不是让类外部使用的,类外部要是想用,在类内部开放接口进行访问,可以达到对外部数据的严格控制
                                             
"""
class Student():
    __school = 'SH' # _Student__school   => _类名__属性名
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    def __tell_info(self): # _Student__tell_info  => _类名__函数名
        print('name:%s,age:%s'%(self.__name,self.age))

    def get_school(self):
        return self.__school
    def set_school(self,v):
        if type(v) is not str:
            print('数据不合法')
        # if isinstance(v,str):
            return 
        self.__school = v

property装饰器

class Student():
    __school = 'SH'  # _Student__school => _类名__属性名

    def __init__(self,name,age):
        self.__name = name
        self.age =age

    def __tell_info(self):  # _Student__tell_info  => _类名__函数名
        print('name:%s,age:%S'%(self.__name,self.age))

    @property # 把方法伪装成函数
    def name(self):
        return 'name:%s'% self.__name

    @name.setter
    def name(self,v):
        if type(v) is not str:
            print('数据不合法')
        # if isinstance(v,str):
            return
        self.name = v

    @name.deleter
    def name(self):
        print('不让删')

stu = Student('ly',18)
print(stu.name)  # name:ly

stu.name = 123
print(stu.name)  # 数据不合法 name:ly

del stu.name  # 不让删

# 练习
class Bmi():
    def __init__(self,height,weight):
        self.height = height
        self.weight = weight

    @property
    def get_bmi(self):
        return self.weight// (self.height ** 2)

bmi = Bmi(1.7,90)
print(bmi.get_bmi)

# 了解

class Student():
    __school = 'SH' # _Student__school  => _类名__属性名

    def __init__(self,name,age):
        self.__name = name
        self.age = age

    def __tell_info(self): # _Student__tell_info  => _类名__属性名
        print('name:%s,age:%s'%(self.__name,self.age))

    def get_name(self):
        return 'name:%s' % self.__name

    def set_name(self, v):
        if type(v) is not str:
            print('数据类型不合法')
            # if isinstance(v, str):
            return
        self.__name = v

    def del_name(self):
        print('不让删')


# 了解

    name = property(get_name,set_name,del_name)


stu =Student('ly',18)
print(stu.name)

stu.name = 'aaa'
print(stu.name)
posted @ 2021-12-02 16:47  Zzy的Bk  阅读(87)  评论(0)    收藏  举报