类的进阶

 

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

 

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

 

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

 

     注意:初始化时会将对象当形参(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)

原文地址:https://www.cnblogs.com/gjx1212/p/11589686.html