zoukankan      html  css  js  c++  java
  • python 面向对象静态方法、类方法、属性方法、类的特殊成员方法

    静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性。

    在类中方法定义前添加@staticmethod,该方法就与类中的其他(属性,方法)没有关系,不能通过实例化类调用方法使用类变量,只能单纯的使用方法本身。

    class dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self,food):
            print '%s吃%s'%(self.name,food)
    a=['q','a','z']
    for i in a:
        d=dog(i)
        d.eat('baozi')
    结果:
    q吃baozi
    a吃baozi
    z吃baozi
        
    
    class dog(object):
        def __init__(self,name):
            self.name=name
        @staticmethod  #实际跟类没有任何关系。
        def eat(self,food):
            print '%s吃%s'%(self.name,food)
    a=['q','a','z']
    for i in a:
        d=dog(i)
        d.eat('baozi')
    

    结果:

    Traceback (most recent call last):
    File "C:Usersxuxiaworkspacehellowordsrc estlianx_2.py", line 223, in <module>
    d.eat('baozi')
    TypeError: eat() takes exactly 2 arguments (1 given)

    class dog(object):
        def __init__(self,name):
            self.name=name
        @staticmethod
        def eat():
            print '%s吃%s'%('w','e')
    d=dog('tt')
    d.eat()
    
    结果:w吃e
    

    类方法:只能访问类变量,不能访问实例变量。

    class dog(object):
        name='hh'
        def __init__(self,name):
            self.name=name
        @classmethod
        def eat(self):
            print '%s吃%s'%(self.name,'e')
    d=dog('tt')
    d.eat()
    结果:hh吃e
    

    属性方法:把一个方法变成静态属性。

    class dog(object):
        name='hh'
        def __init__(self,name):
            self.name=name
        @property
        def eat(self):
            print '%s吃%s'%(self.name,'e')
    d=dog('tt')
    d.eat      #
    结果:tt吃e
    

    如果给属性方法传参数,需要重新写方法,如:eat

    class dog(object):
        name='hh'
        def __init__(self,name):
            self.name=name
        @property
        def eat(self):
            print '%s吃%s'%(self.name,'e')
        @eat.setter
        def eat(self,food):
            print '%s is eating %s'%(self.name,food)   
        
    d=dog('tt')
    d.eat='baozi'
    
    结果:tt is eating baozi
    

    类的特殊成员方法:

    ddd.py

    class c(object):
       def __init__(self,name):
           self.name=name
       def a(self):
           print 'bb%s'%self.name
    
    from ddd import c
    b=c('ee')
    print b.__module__
    

    结果:ddd

    print b.__class__
    

    结果:<class 'ddd.c'>

     __call__ 对象后面加括号,触发执行

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

    class dog(object):
        '''方法__call__实例'''
        def __init__(self,name):
            self.name=name
        def a(self):
            print'sssss%s'%self.name
        def __call__(self,*c,**f):
            print c,f       
            
    d=dog('ddd')
    d.a()
    dog('ddd')(1,2,3,f='fff')
    
    
    结果:
    sssssddd
    (1, 2, 3) {'f': 'fff'}
    

    __dict__ 查看类或对象中的所有成员

    class dog(object):
        '''方法__dict__实例'''
        def __init__(self,name,food):
            self.name=name
            self.food=food
        def a(self):
            print'sssss%s'%self.name
        def __call__(self,*c,**f):
            print c,f 
            
    print dog.__dict__
    d=dog('ddd','nome')
    print d.__dict__ #打印所有类属性,不包括类变量
    
    
    结果:
    {'a': <function a at 0x02229C70>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'dog' objects>, '__call__': <function __call__ at 0x02229C30>, '__weakref__': <attribute '__weakref__' of 'dog' objects>, '__doc__': 'xe6x96xb9xe6xb3x95__call__xe5xaex9exe4xbex8b', '__init__': <function __init__ at 0x02229CB0>}
    {'food': 'nome', 'name': 'ddd'}
    

    __str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

    class dog(object):
        '''方法__str__实例'''
        def __init__(self,name,food):
            self.name=name
            self.food=food
        def a(self):
            print'sssss%s'%self.name
            return self.name #实例化后方法的返回值,实例化后必须复制给变量
        def __call__(self,*c,**f):
            print c,f 
        def __str__(self):
            return self.food  #类的返回值,实例化后指对象的返回值
            
    d=dog('xx','yy')
    f=d.a()
    print f
    print d
    结果:
    sssssxx
    xx
    yy
    

    __getitem__、__setitem__、__delitem__

    class Foo(object):
        '''__getitem__、__setitem__、__delitem__实例'''
        def __getitem__(self, key):
            print('__getitem__',key)
    
        def __setitem__(self, key, value):
            print('__setitem__',key,value)
    
        def __delitem__(self, key):
            print('__delitem__',key)
    obj = Foo()
    result = obj['k1']      # 自动触发执行 __getitem__
    obj['k2'] = 'alex'   # 自动触发执行 __setitem__
    del obj['k1'] 
    
    结果:
    ('__getitem__', 'k1')
    ('__setitem__', 'k2', 'alex')
    ('__delitem__', 'k1')
    

    __new__ __metaclass__

    class Foo(object):
        def __init__(self,name):
            self.name = name
    f = Foo("alex")
    

      上述代码中,f 是通过 Foo 类实例化的对象,其实,不仅 f是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

    如果按照一切事物都是对象的理论:f对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

    print type(f) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建
    print type(Foo) # 输出:<type 'type'>              表示,Foo类对象由 type 类创建
    

    所以,f对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

    那么,创建类就可以有两种方式:

    a). 普通方式 

    class Foo(object):
     
        def func(self):
            print 'hello alex'
    

    b). 特殊方式

    def func(self):
        print 'hello wupeiqi'
     
    Foo = type('Foo',(object,), {'func': func})
    #type第一个参数:类名
    #type第二个参数:当前类的基类
    #type第三个参数:类的成员
    def f(self):
        print "f"
    def __init__(self,name):
        self.name=name
    foo=type('foo',(object,),{'__init__':__init__,'f':f}) #注意元祖object后有逗号
    d=foo('xx')
    d.f()
    
    结果:f
    

    __new__:用来创建实例的。

    类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__,一般不要写__new__方法,因为该方法已经在类中写好,重写的话,只能覆盖类中的方法。

    class foo(object):
        def __init__(self,name):
            self.name=name
            print '__init__%s'%self.name
        def __new__(cls,*c,**f):  #先创建new方法
            print '__new__'
            return object.__new__(cls)  #通过__new__方法创建(触发)__init__方法
    f=foo('xx')
    print f
    
    结果:
    __new__
    __init__xx
    <__main__.foo object at 0x021E51F0>
    

     类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程

    详细查看:http://www.cnblogs.com/alex3714/articles/5213184.html

  • 相关阅读:
    深浅拷贝
    生成式、生成器、迭代对象、迭代器
    memcached
    redis安装配置
    基于docker搭建mysql主从复制架构
    centos 安装 最新版本的docker
    Linux小技巧
    神奇的'license': 'AGPL 3.0'标签报错
    新博客重新开通了
    通过linkserver不能调远程表值函数
  • 原文地址:https://www.cnblogs.com/iexperience/p/9198651.html
Copyright © 2011-2022 走看看