zoukankan      html  css  js  c++  java
  • 面向对象基础

    面向过程编程

    关键在于过程
    
    过程指的是,先干啥 再干啥 最后干啥,设计思想好比一条流水线
    注意:面向过程与函数编程是完全不同的
    优点:将复杂的问题流程化,简单化
    缺点:由于代码严格按照流程编写,导致扩展性极差
    -----------------------------------
    #面共对象对比面向过程
    #使用面向对象来编写程序时,不去思考具体的实现步骤,重点是什么样的对象可以完成这个事情
    面向过程想的是:怎么做
    面向对象想的是:谁来做
    
    优点:扩展性高,修改单独某一个对象,不会影响其他对象灵活度,复用性,降低耦合度
    缺点:1、相对于面向过程而言,编程的复杂度提高了
       2、无法准确预知执行结果
    
      使用场景:对扩展性要求较高的应用程序(面向用户的应用程序扩展性较高)
    View Code

    一、面向对象简介

    #什么是面向对象
        是一种编程思想
        关键在于对象,
    #什么是对象:一系列特征和技能的结合体
    
    ------------------------------------------------------
    1、使用面型对象开发,第一步是设计 类
    2、使用  类名()  创建对象,创建对象的动作有两步:
               1)在内存中为对象分配空间
               2)调用初始化方法__init__ 为对象初始化
    
    3、对象创建后,内存中就有了一个对象的  实实在在 的存在--实例
    
    
    因此,通常会把:
    1、创建出来的  对象 叫做 类的实例
    2、创建对象的 动作 叫做实例化
    3、对象的属性叫做实例属性
    4、对象的调用方法叫做实例方法
    
    在程序执行时
    
    1、对象各自拥有自己的 实例属性
    2、调用对象方法,可以通过self.
            访问自己的属性
            调用自己的方法
    
    结论
    ·每一个对象  都有自己 独立的内存空间 ,保存各自不同的属性
    ·多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用 传递到方法的内部
    面向对象简介

    二、类与对象基础

    #2.1类和对象的关系
        生活中:先有对象,再有类  (先有人,再有人类)
        程序中:先有类,再由类产生对象  (先定义需求,再产生对象
    
    
    #2.2什么是类
        类是一系列相同特征(变量)与技能(函数)的对象的结合体,即类体中最常见的就是变量和函数的定义
    
    
    #2.3类的本质
        类体代码会在类定义阶段立即执行,会产生一个类的名称空间,用来将类体代码执行过程中产生的名字都丢进去
        本质:是一个名称空间,或者说是一个用来存放变量与函数的的容器
    
    
    #2.4类的用途
        类的用途之一:当做名称空间从内部取出名字来使用
        类的用途之二:调用类来产生对象

     三、对象传值的两种方式

    class Student:
    
        def choose_course(self):
            pass
    
    stu1=Student()
     
    stu1.name = 'pdun'           #对象.
    stu1.age = 1
    stu1.sex = 'man'
    View Code
    #__init__的功能:是在实例化时就为对象初始自己独有的特征
    #注意:不能有返回值
    
    
    class Student:
        def __init__(self,name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    stu =Student('pdun',1,'man')
    init

    类方法

    #类方法可以直接被类调用,不需要对象
    #当一个方法只涉及改变静态属性(类中的变量)时,应考虑用@classmethod
    class Goods():
        price=10
        @classmethod
    
        def new_price(cls,new_price):
            cls.price=new_price
            print(cls.price)
    
    Goods.new_price(5)
    obj = Goods()
    print(obj.price)
    View Code

     静态方法

    #在完全面向对象编程中,如果一个函数,既和对象没有关系,也与类没有关系,就用staticmethod把它变成静态方法,使用时直接    对象.该方法
    class Static():
    
        @staticmethod
        def login():
            user = input('用户名:')
            pwd = input('密码:')
            print(user,pwd)
    
    Static.login()
    View Code
    #总结
    1、类方法和静态方法都是类调用的
    2、对象可以调用静态方法和类方法吗?  可以,但一般推荐类调用
    3、静态方法没有参数,它就相当于一个普通的函数,只不过在调用的时候多加一个类名罢了,它相当于普通函数,当然可以传参

     

     元类

    #exec:三个参数
    
    #参数一:包含一系列python代码的字符串
    
    #参数二:全局作用域(字典形式),如果不指定,默认为globals()
    
    #参数三:局部作用域(字典形式),如果不指定,默认为locals()
    
    #可以把exec命令的执行当成是一个函数的执行,会将执行期间产生的名字存放于局部名称空间中
    
    例如
    
    class_dic = {}
    exec("x=1",{},class_dic)
    print(class_dic)
    >>{'x': 1}
    会把x=1执行时产生的名称空间放到class_dic中
    如果在执行代码时需要用到全局的名称空间,就到参数二中找
    #拿到类名
    class_name = "OldBoy"
    
    #拿到类的基类们
    class_bases = (object,)
    
    #执行函数体代码,拿到名称空间
    class_dic = {}
    
    x = """
    school = "oldboy"
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def score(self):
        print("name is %s" % self.name)
    """
    exec(x,{},class_dic)   #执行代码,将所产生的名称空间放到class_dic中
    print(class_dic)
    OldBoy = type(class_name,class_bases,class_dic)  #调用元类得到类
    class关键字底层工作原理
    #!!但凡继承了type的类,才称之为元类,否则只是普通的类!!
    class Mymetaclass(type):
        def __init__(self,class_name,class_bases,class_dic):
            print(self)
            print(class_name)
            print(class_bases)
            print(class_dic)
    class OldBoy(metaclass=Mymetaclass):
        a = 1
        def __init__(self,name):
            self.name = name
    
    ------------------------------------------------------
    #错误的
    class Mymetaclass(type):
        def __init__(self):     #错误在此处
            print(self)
    class OldBoy(metaclass=Mymetaclass):
        a = 1
        def __init__(self,name):
            self.name = name
    
    >>TypeError: __init__() takes 1 positional argument but 4 were given
    
    #说明底层原理是
    #OldBoy = Mymetaclass(OldBoy ,class_bases,class_dic)
    #需要把自身,类名,类的基类,所产生的名称空间一起传给元类

     自定义元类控制类的产生

    自定义元类可以控制类的产生过程,类的产生过程其实就是元类的调用过程,
    即OldboyTeacher=Mymeta('OldboyTeacher',(object),{...}),
    调用Mymeta会先产生一个空对象OldoyTeacher,
    然后连同调用Mymeta括号内的参数一同传给Mymeta下的__init__方法,完成初始化,于是我们可以
    class Mymeta(type): #只有继承了type类才能称之为一个元类,否则就是一个普通的自定义类
        def __init__(self,class_name,class_bases,class_dic):
            # print(self) #<class '__main__.OldboyTeacher'>
            # print(class_bases) #(<class 'object'>,)
            # print(class_dic) #{'__module__': '__main__', '__qualname__': 'OldboyTeacher', 'school': 'oldboy', '__init__': <function OldboyTeacher.__init__ at 0x102b95ae8>, 'say': <function OldboyTeacher.say at 0x10621c6a8>}
            super(Mymeta, self).__init__(class_name, class_bases, class_dic)  # 重用父类的功能
    
            if class_name.islower():
                raise TypeError('类名%s请修改为驼峰体' %class_name)
    
            if '__doc__' not in class_dic or len(class_dic['__doc__'].strip(' 
    ')) == 0:
                raise TypeError('类中必须有文档注释,并且文档注释不能为空')
    
    class OldboyTeacher(object,metaclass=Mymeta): # OldboyTeacher=Mymeta('OldboyTeacher',(object),{...})
        """
        类OldboyTeacher的文档注释
        """
        school='oldboy'
    
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def say(self):
            print('%s says welcome to the oldboy to learn Python' %self.name)
    自定义元类控制类的产生

     自定义元类控制类的调用

        

        

        

  • 相关阅读:
    c++中的数据类型
    C语言堆栈入门——堆和栈的区别
    用(*.frm *.MYD *.MYI)文件恢复MySql数据库
    GridView总结二:GridView自带编辑删除更新
    GridView总结一:GridView自带分页及与DropDownList结合使用
    对自己寒假的安排
    Python3 File
    Python3输入输出
    Python模块
    Python3数据结构
  • 原文地址:https://www.cnblogs.com/pdun/p/10396642.html
Copyright © 2011-2022 走看看