zoukankan      html  css  js  c++  java
  • Python类的构成元素

                                       类的构成元素


    公共属性:实例化时无需__init__方法绑定到对象,就可以直接使用;
    普通属性:实例化时 需要__ini__方法绑定到对象之后,才可以直接使用;
    私有属性:__sex 双下滑杠开头,需要在类里定义函数属性(方法),对象调用函数属性间接访问;
    特性
    使用@property装饰器的方法,特性就是类的特殊属性,特殊之处在于普通属性是变量赋值的形式存在,它是一段代码(函数)返回值,因此可以借助@property把函数属性,模拟成变量属性,统一了调用接口;

    特性分类:
    1、只读特性@property装饰的函数
    2、@diaplay.setter 可修改的特性
    3、@diaplay.deleter 可以删除特性
    --------------------------------------------------------------------------------------------------------------------------------------
    绑定方法:实例调用时,该函数属性的 第一个形参自动传入对象本身;
    静态方法@staticmethod装饰的函数,称之为静态方法,无论对象还是类调用他,都不会把自身当做其第一个参数传入;说白了就是在类里定义了一个普通函数;也可以称为解绑函数,给类使用;

     类方法:类方法是给类用的,类在使用时会将类本身当做参数传给类方法的第一个参数,python为我们内置了函数classmethod来把类中的函数定义成类方法;1

    类的特殊方法:

    0、__init__  (类里定义__init__构造方法,对象实例化时,触发__init__构造方法 初始化属性给对象)

    1、__setattr__ (类里定义了__setattr__方法,对象设置属性时,触发该特殊方法执行;)

    2、__delattr__(类里定义了__delattr__方法,对象删除属性时,触发该特殊方法执行;)

    3、__getattr___ (类里定义了__getattr__方法,对象找不到属性时,触发该特殊方法执行;)

    4、__str__(在类里定义__str__特殊方法,print 打印由这个类实例化出来的对象时,就会显示__str__特殊方法return的结果)

    5、__setitem__(对象以字典的形式,设置属性时就会触发 ____setitem__特殊方法的运行)

    6、__getitem__(对象以字典的形式,获取属性时就会触发__getitem__特殊方法的运行)

    7、__delitem__(对象以字典的形式,删除属性时就会触发__delitem__特殊方法的运行

    8、__slots__ (在类里定义__slots__ 特殊方法之后,所有对象实例化时 自己不会再创建名称空间__dict__而且只能使用 __slots__ = ['x','x1','x2']里定义的属性)

    9、__iter__和__next__(有__iter__方法的对象可迭代对象,可迭代对象执行__iter__方法变成迭代器;迭代器调用__next__就可以取一个迭代器里值,这样就不依赖索引取值了。)

    10、__doc__(定义类的描述信息)

    11、__del__(析构方法,当对象在内存中被释放时,自动触发执行。无需Python解释器回收垃圾;)

    12、__enter__和__exit__(实现上下文管理协议 with open('a.txt','m') as f)

    13、__call__(在类里定义了__call__实例化出来的对象,加上括号()就直接调用了__call__特殊方法里return的结果 )

    14、__dict__(对象的属性和属性值)

    class BaseReponse:
        def __init__(self):
            self.status = False
            self.data = None
            self.error = None
            self.msg = None
    
        def get_dic(self):
            #返回1个对象的属性信息
            return self.__dict__
    
    response=BaseReponse()
    response.error=1
    print(response.get_dic())
    __dict__应用

    15、__bases__(查看当前类继承的父类)


    对象属性 # 对象私有属性(对象不可以直接访问) # 绑定方法:但凡定义到类里面的方法都是 绑定方法;对象调用绑定方法,会自动把自己作为绑定方法的第一个参数,传进去; #静态方法:解除绑定关系,本质上就是个函数,类和对象直接调用,不用传自己;所也以对象 不用实例化 也可以使用类里的方法了; # 对象特性:property通过对象方法模拟出来的property(对象的特性 会 优先于对象属性被访问) # 对象特性分为 #
    1.只读特性 2.可修改特性 3、可删除的特性 # class People(): # def __init__(self,Name,Sex): # self.name=Name #self.name是对象实例时,调用__init__方法时,初始化给对象的属性; # self.__sex=Sex #但凡属性有__(双下划线标识)就意味着着,这是初始化给对象的私有属性,对象不能直接访问; # def diaplay(self): #如何访问私有属性呢? # return self.__sex # 1、通过在类里 添加方法,对象通过这个借口访问; # # p=People('马腾飞','') # print(p.diaplay()) # # class People(): # def __init__(self, Name, Sex): # self.name = Name # self.__sex = Sex # @property #2、通过类类内部的方法访问__sex还需要加括号,于是在此基础上,有了 @property装饰器。 # def diaplay(self): #@property: 通过装饰类的方法,给对象模拟出一个只读属性;就是负责把一个方法变成属性调用的: # return self.__sex # p1=People('黄蓉','') # p1.diaplay #这样通过 diaplay方法 模拟出来的diaplay属性 就可以,像访问普通属性一样的方法,访问私有属性了; # print(p1.__dict__) # # # class People(): # def __init__(self, Name, Sex): # self.name = Name # self.__sex = Sex # #@property装饰器虽然解决了,私有属性 、方法的统一访问;模拟出了私有属性访问接口; # @property # 但该 接口无法 修改,私有属性还是无法修改; # def diaplay(self): # return self.__sex # @diaplay.setter #于是在此基础上产生了@diaplay.setter 装饰器,可修修改 @property特性 # def diaplay(self,value): # self.__sex=value #千万注意 @display_setter只是模拟出来的特殊属性,没有存储值得功能;所以要修改他的值一定要修改 他引用的真实值 # return # # p2=People('黄蓉','') # print(p2.diaplay) # p2.diaplay='male' # print(p2.diaplay) # # class People(): # def __init__(self, Name, Sex): # self.name = Name # self.__sex = Sex # @property # def diaplay(self): # return self.__sex # @diaplay.setter # def diaplay(self,value): # self.__sex=value # return # @diaplay.deleter #可删除 property 特性 # def diaplay(self): # del self.__sex # # p3=People('黄蓉','') # print(p3.diaplay) # del p3.diaplay # print(p3.diaplay) import time # class Date: # def __init__(self,Year,Month,Day): # self.year=Year # self.month=Month # self.day=Day # @staticmethod #@staticmethod,给类增加了一种新的实例化方式,直接调用类下面的方法,不用__init__ # def now(): #用Data.now的形式去产生对象,该实例用的就是当前的时间 # t=time.localtime() # obj=(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回 # return obj # # print(Date.now()) # # d1=Date.now() # print(id(d1))

     

    1、__setattr__特殊方法

    class Foo:
        def __init__(self,Name,Age):
            self.nmae=Name
            self.age=Age
        def __setattr__(self, key, value):  #既然对象实例化时 设置的属性都不会去 __dict__,而是触发__setattr__就可以对实例化时 传入的值进行类型限制了;
            if not isinstance(value,str):
                raise TypeError( "必须是字符串")
    
            print("""只要在类里定义了__setattr__特性方法,
                   这个类实例对象时,只要有给对象设置属性的 操作,就会触发我__setattr__的运行。
                   传入 这个对象 本身传入我__setattr___的第一个形参
                   传入 这个对象 __dict__的key给第二个形参:--------> %s
                   传入 这个对象__dict__的value给第三个形参:------->%s """ % (key,value) )
            self.__dict__[key]=value      #既然对象实例化时 设置的属性都不会去 __dict__可以这样解决
    
    f1=Foo('egon','22')
    print(f1.__dict__)   #类里有了__setattr__特殊方法,实例化对象时;
                         # 就不会把值写到  f1.__dict__,所以实例化之后 f1.name f.age就会报错,因为f1的字典里没有值;
    f1.age

     2、__delattr__

    class Foo:
        def __init__(self,Name,Age):
            self.name=Name
            self.age=Age
        def __delattr__(self, item):        #__delattr__只要对象实例化之后,有删除属性的操作,就会触发运行;
            print(''''我草了,不要删啊!''')
            self.__dict__.pop(item)        #真正的删除 还需要pop 对象__dict__字典里的key才可以 真正删除;
    
    
    f2=Foo('张根',18)
    print(f2.age)
    del f2.age
    print(f2.__dict__)

    3、__getattr__

    class Foo:
        def __init__(self,Name,Age):
            self.neme=Name
            self.age=Age
        def __getattr__(self, item):  #对象实例化之后调用对象__dict__字典里不存在的属性时,就会触发__getattr__的运行
            print("触发我了")
            print(item)
    
    f3=Foo('张根',18)

    4、__str__

    class foo:
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __str__(self):
            return '我擦!'
    
    f1=foo("c",22)
    print(f1)      #打印有foo类实例出来的对象,就显示__str__方法return的结果,也就是:我擦

    5、__getitem__

    class Foo:
        def __init__(self,name):
            self.name=name
        def __getitem__(self, item):
            print(item)
            print('触发我了')
    #
    # f2=Foo('张根')
    # f2['name']        #对象以字典的形式,获取属性时就会触发__getitem__特殊方法的运行;

    6、__setitem__

    class Foo:
        def __init__(self,name):
            self.name=name
        def __setitem__(self, key, value):
            print('触发我了!')
    
    # f1=Foo('张根')
    # f1['name']='egon'   #对象以字典的形式,设置属性时就会触发 ____setitem__特殊方法的运行
    # # f1['age']=18

    7、__delitem__

    1 class Foo:
    2     def __init__(self,name):
    3         self.name=name
    4     def __delitem__(self, key):
    5         print('触发我了,不要删除;')
    6 
    7 # f3=Foo('张根')
    8 # del f3['name']  #对象以字典的形式,删除属性时就会触发__delitem__特殊方法的运行;

    8、__slots__

    class People:
        __slots__ = ['x','x1','x2']    #在类里定义__slots__ 特殊方法之后,所有对象实例化时 自己不会再创建名称空间__dict__
                                         #而且只能使用 __slots__ = ['x','x1','x2']里定义的属性
    
    # p1=People()
    # p1.x=0
    # p1.x1=1
    # p1.x2=2
    # print(p1.__dict__)  #对象的__dict__不会被创建了

    9、__iter__和__next__特殊方法实现迭代器协议

    class Rangge:
        def __init__(self,start,end):
            self.start=start
            self.end=end
        def __iter__(self):
             return self    #__iter__ 可迭代对象执行它,returun得一个迭代器
        def __next__(self): #迭代器 应该有__iter__和__next__方法;每次调用迭代器 __next__()就可以不依赖索引取迭代器里的值了;
            if self.start==self.end:
                raise  ImportError("SSS")
            s=self.start
            self.start+=1
            return s
    
    r=Rangge(0,100)
    print(r.__next__())
    print(r.__next__())
    
    for i in r: #1、res=r.__iter__() 2、 res.__next__() for循环会自动调用r得__iter__()方法,把r变成一个迭代器。然后调用迭代器的__next__()方法一下一下得遍历r;
        print("--------->%s"%i)
    
    i = iter('abcd')
    print(i.__next__())
    print(i.__next__())

    10、__enter__和__exit__ 特殊方法实现上下文协议 with open(‘a.txt’ ,'w')as f:

    class foo:
        def __enter__(self):
            print('=========>')
            return "86"
        def __exit__(self, exc_type, exc_val, exc_tb):  #最方法后执行的 __exit__特殊方法
            print(exc_type,exc_val,exc_tb)
            return True  #return就等于告诉 解释器不要抛出异常
    
    
                            #with foo()得到一个对象,  对象调用enter方法讲执行的结果 return的结果赋值给 as后面的对象;
    with foo() as obj:     #with foo()= with foo().enter()       res=with foo().enter() =obj
                            #1、 with foo()得到一个对象,就会触发对象的__enter__方法的执行,2、执行with语句的子代码 3、走__exit__
        print("with的子代码。。。%s" %obj)
        raise TypeError("类型错误")

    11、__enter__和__exit__ 特殊方法实现上下文操作文件

    class Open:
        def __init__(self,file_path,mode):
            self.file_path=file_path
            self.mod=mode
            self.f=open(file_path,mode=mode)
    
        def write(self,line):
            self.f.write(line)
    
        def __getattr__(self, item):
           return getattr(self.f,item)
    
        def __enter__(self):
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            return True
    
    with Open('a.txt','r') as f:
       raise TypeError("SSSSSS")

     13、__call__

    class foo:
        def __init__(self,Name,Age,Sex):        #注:构造方法的执行是由创建对象触发的,即:对象 = 类名()
            self.name=Name
            self.age=Age
            self.sex=Sex
    
        def __call__(self, *args, **kwargs):  #对象本身是无法执行的,类里定义了__call__特殊方法,由这个类实例化出来的对象就可以执行了;
            print("这个类实例化,出来的对象加上括号,就调用我")
    # f=foo()  #构造方法的执行 也是创建对象触发的,即:对象 = 类名()
    # f()
  • 相关阅读:
    jquery deferred对象
    一张图道尽Javascript的原型继承
    Reflection
    vim操作
    转载:HTTP调试工具:Fiddler的使用方法介绍
    转载:计算机网络面试题
    20120810
    new pad不能用usb充电的解决方法
    20120416
    Lua入门——环境安装
  • 原文地址:https://www.cnblogs.com/sss4/p/6747421.html
Copyright © 2011-2022 走看看