zoukankan      html  css  js  c++  java
  • 类的进阶

     

    一.类的存储与实例对象的存储

     

        类定义好后会为类开辟一块空间。

     

         实例化一个类后会将初始化的数据和对象名一并传入类中,并在类的外面开辟一块空间用于存数据。

     

         注意:初始化时会将对象当形参(self)传入类

     

                     实例对象不会将类中共同的方法或变量的存下来,而是通过self进行访问。

     

    二.变量的分类

     

    实例属性(静态属性)只对该实例对象有作用域

    实例方法(动态属性)只对该实例对象有作用域

    类变量     对所有的实例对象都有作用域,只存放在类里面

    注意:当类变量与实例变量矛盾时,实例变量有效,通过实例改类变量时,是将类变量复制一份到该实例对象中 ,将复制后的进行修改。但list不一样,通过实例改类变量的list时就是在类中修改。

    二.构造函数

     

     

    class Dog:
        def __init__(self,name,age,salary):
                    self.name = name self.age = age self.salary = salary#等号的左右的名称可以不同,左边是属性名,右边是形参名
           def bulk(self,voice)
                        print('%s is bulking,,,,%s' %s(self.name,voice)) 
           def __del__():
                    print('我是析构函数')
     taidi = Dog(taidi,3,2300)
    
    taidi.bulk()

     

     

        作用:实例化类时,进行初始化,并开辟一块空间。但不会将类中的方法都复制一边

     

                 

     

       实例化类时构造函数会自动执行

     

         三.析构函数  

    但不能有参数,实例释放和销毁时自动执行,进行扫尾工作,如关闭数据库链接。

         四.私有属性,私有方法

            私有属性或方法名前加  __(双下划线)外部不能访问,但可以通过类中其他的方法访问。

             

       五.继承

         在构造一个类时将要继承的父类当做参数传入。

    class  school_member(object):    #父类,object是基类,是新式类的写法
        def __init__(self,name,age,id):
               self.name=name
               self.age=age
               self.id=id
        def   enroll(self):     #注册函数
               print('welcom to %s"%self.name)
    
    
    
    class  student(school_member):
         def __init__(self,name,age,id,money):
               #school_member.__init__(self,name,age,id)
                 super(sudent,self).__init__(name,age,id)
                 self.money=money
           

    六.多继承

        多继承的顺序,分为广度优先和深度优先

    Python3中新式类和经典类都是广度优先

    Python2中   新式类是广度优先     经典类是深度优先

    class  A(object):
          def __init__(self):
                   print('A')
    
    class   B(A):
          def __init__(self):
                print('B')
     
    class   C(A):
           def __init__(self):
                  print('C')
    class   D(B,C):
           def __init__(self):
                  print('D')

    说明:B,C继承了A,而D继承B,C

    广度优先:先在B中找有没有构造函数,没有再在C中找,最后在A中找

    深度优先:在B中找没有再再A中找,后面依次类推。

    多继承的顺序是按参数从左向右。并依次寻找是否有构造函数,有了就不执行后面的构造函数,前面构造的属性,可以在另一个父类中调用。

    class School(object):
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
            self.students=[]
            self.teachers=[]
            self.couses=[]
            self.greens=[]
        def encoll(self,stu_obj):
            self.students.append(stu_obj)
            print("欢迎%s来到%s"%(stu_obj.name,self.name))
        def hair(self,teacher_obj):
            self.teachers.append(teacher_obj)
        def couse(self,cou_obj):
            self.couses.append(cou_obj)
        def green(self,gren_obj):
            self.greens.append(gren_obj)
    
    class Sch_member(object):
        def __init__(self,name,sex,age):
            self.name=name
    
            self.sex=sex
            self.age = age
    
    class Teacher(Sch_member):
        def __init__(self,name,sex,age,salary,couse_obj,green_obj,id,sch_obj):
            super(Teacher, self).__init__(name.sex,age)
            self.salary=salary
            self.couse=couse
            self.green=green
            self.id=id
            self.school=sch_obj
    
        def teach(self):
            print("%s teaching the class %s of %s"%s(self.name,self.green,self.couse))
    class Student(Sch_member):
        def __init__(self,name,sex,age,id,green_obj,sch_obj):
            # type: (object, object, object, object, object, object) -> object
            super(Student,self).__init__(name,sex,age)
            self.id=id
            self.green=green_obj
            self.school=sch_obj
    
        def choose_couse(self,name,addr,name1,teacher_obj,time,priser,green_obj):
            print("请选择课程")
            self.couses.append(Couse(name,addr,name1,teacher_obj,time,priser,green_obj))
    class green(School):
        def __init__(self,name,addr,name1,teacher_obj,couse_obj):
            super(green, self).__init__(name,addr)
            self.teacher=teacher_obj
            self.couse=couse_obj
    
    class Couse(School):
        def __init__(self,name,addr,name1,teacher_obj,time,priser,green_obj):
            self.name=name1
            super(Couse, self).__init__(name,addr)
            self.teacher=teacher_obj
            self.time=time
            self.priser=priser
            self.green=green_obj
    
    B_sch=School("Beijing universtry","beijing")
    S_sch=School("fudan universtry","shanghai")
    g_01=green("Beijing universtry","beijing","苹果班",teacher1,c_language)
    B_sch.green(g_01)
    g_02=green("fudan universtry","shanghai","仙女班",teacher2,python)
    S_sch.green(g_01)
    c_language=Couse("Beijing universtry","beijing","c",teacher1,"8:00-12:00",12000,g_01)
    B_sch.green(c)
    python=Couse("fudan universtry","shanghai","Python",teacher2,"8:00-12:00",12000,g_02)
    S_sch.green(python)
    teacher1=Teacher("alex","",22,21000,c_language,g_01,1001,B_sch)
    B_sch.hair(teacher1)
    teacher2=Teacher("oldboy","",32,41000,python,g_02,10002,S_sch)
    S_sch.hair(teacher2)
    '''stu1 = Student("xiaoling","男",23,0001,g_01,B_sch)
    B_sch.encoll(stu1)
    stu2 = Student("hanshangyan","女",23,0002,g_02,S_sch)
    S_sch.encoll(stu2)'''

       七.多态

             一个接口,多个实现,即通过一个接口的调用实现多个功能

    class animal(object):
        def __init__(self,name,age)    
            self.name = name
            self.age = age
        def eat(self):
            print("%s is eating %s"%(self.name,sself.food))
    '''多态的实现'''
        @staiticmethod
        def animal_food(obj):
            obj.eat()
    
    class Dog(animal):
        def __init__(self,name,age,food)
            super(Dog,self).__init__(name,age)
            self.food = food
    d1=Dog(taidi,2,bone)
    d2 = Dog(bianmu,3,chiken)
    animal.eat(d1)
    animal.eat(d2) 

          八.静态方法,类方法,属性方法

     

        1.静态方法   @staticmethod

              名义上是类的方法,但与类没有什么联系,除了必须要通过类的实例调用,但该方法不能调用类或实例中的任何属性,同时它可以没有参数,正常的方法必须至少有一个self参数

         2.类方法   @classmethod

          只能访问类的变量,不能访问实例属性

        3.属性方法 @porperty

            将一个方法函数变成属性,同时可以通过@方法名.setter进行设置  用@方法名.deltter进行删除属性,(设置属性的本质是在类属性一开始写好,但不传参,通过该方法进行传参),

    class  perpol(object):
        n= "i am class var"
        def __init__(self,name):
             self.name = name
             self.__food
        @staticmethod
        def test1():
             print("in the static")
        @porperty
        def eat(self):
              print("%s is eating %s"%(self.name,self.__food))
        @eat.setter
        def eat(self,food):
             print("set porperty done")
             self.__food = food
        @eat.deltter
         def eat(self):
              del self.__food
      
    
    p1 =perpol("alex",23)
    p1.test1()
    p1.eat 
    p1.eat = "包子"#进行属性设置时自动调用
    del p1.eat#进行删除操作时自动执行上面的函数
        

     九.各种内置方法

    1.__dict__  

           返回所有的方法与属性,当是类名时返回类中的属性与方法,若是实例时返回值实例的         属性

    2.__module__/__class__     

          __module__     返回导入该类对应的模块

          __class__     返回模块和类名(路径)

    3.__setitem__/getitem__/__delitem__

         给类添加字典的功能,

         

    class Foo(object):
        def __init__(self,name):
             self.name=name
             self.date={}
        def __setitem__(self,key,value):
             print(have set done)
             self.date[key]= value
        def __getitem__(self,key):
             print(self.date[key])
        def __delitem__(self,key):
             del self.date[key]
    f=Foo('alex')
    f[age]=23#自动调用__setitem__
    print(f[age])#调用__getitem__
     

     4.__doc__

    打印类名时会打印出注释语句

    5.__str__

    打印实例名时会打印改函数的返回值,用于了解实例对象

    6.__call__

    class Foo(object):
        def __call__(self):
             print(in the call)
    f=Foo()
    f()#在实名后加括号调用call函数

    在类后面加括号自动执行__init__,在实例名后加括号自动执行__call__

     类的类是type

    通过type方法来定义一个类,将没有关系的函数通过type联系起来了

    def __init__(self,name,age):
        self.name=name
        self.age=age
    def information(self):
        print('the name is',name)
    Foo=type('Foo',(object,),{'__init__':__init__,
                               'fanc':information})
    f=Foo('高佳雪',20)
    f.information()

     7.__metaclass__  类中的一个属性__metaclass__表示该类由谁实例化创建,因此可以为__metaclass__设置一个type类的派生类

      

    class MyType(type):
        def __init__(self,what,bases=None,dict=None):
            surper(MyType,self).__init__(what,bases,dict)
        def __call__(self,*args,**kwargs):
            obj=self.__new__(self,*args,**kwargs)
            self.__init__(obj)
      
    
    class Foo(object):
        __metaclass__ = MyType
        def __init__(self,name):
            self.name=name
        def __new__(cls,*args,**kwargs):#cls是MyType中的obj
            return object.__new__(cls,*agrs,**kwargs)
     
    obj = Foo()

     类的实例实际是通过__new__方法创建的self就是__new__函数的返回值,即为实例开辟的一块空间

    十.反射

      通过字符串映射或修改程序运行时的状态,属性,方法

      1.getattr( object, name, default=none )  根据字符串获取obj对象里对应的方法的内存地址

      2.hasattr( object, name_str )  判断一个对象object里是否有对应的name_str字符串对应的属性或方法

      3.setattr(x ,y ,v)  x是实例对象,y是字符串名,v是方法或属性

      4.delattr(x, y )   x,y同上

    class Foo(object):
         def __init__(self,name):
              self.name=name
    
    f = Foo('alex')
    def bulk(self):
         print('%s is bulking',%self.name)
    choice = input("输入方法或属性").strip()
    if hasatter(f,choice):
         getatter(f,choice)#如果是方法可以改为 choice = getatter(f,choice)    choice(f)
    else:
         setatter(f,choice,bulk)#f.choice=bulk
         func =  getatter(f,choice)
         func(f)

  • 相关阅读:
    程序启动冲出UAC解决Win UAC问题的编程经验
    代码服务器端Tornado实现聊天室功能(websocket)
    选中菜单android中的显示跳转和隐式跳转
    提交优化Oracle Tuning Log File Sync 等待事件的几种策略
    对象类Effective Java:Ch3_Methods:Item11_谨慎重写clone()
    视频教程视频Java+PHP+.NET海量教程来了 500G教程
    应用性能Intel MIC适合什么样的应用程序
    资源页面dwr的ajax实现
    登录用户Eclipse中SVN访问用户的变更办法
    内存释放[置顶] Cocos2dx 内存管理心得
  • 原文地址:https://www.cnblogs.com/gjx1212/p/11589686.html
Copyright © 2011-2022 走看看