zoukankan      html  css  js  c++  java
  • 类的特殊成员方法

    1. __doc__  表示类的描述信息

    class Dog(object):
    '''这个类是描述狗这个对象的'''
    def func(self):
    pass


    print(Dog.__doc__)
    # 输出:类的描述信息

    2. __module__ 和  __class__ 


    __module__ 表示当前操作的对象在那个模块

    __class__ 表示当前操作的对象的类是什么

    #lib/aa.py中代码如下:
    class C:

    def __init__(self):
    self.name = 'wupeiqi'

    #index.py中代码如下:
    from lib.aa import C

    obj = C()
    print(obj.__module__) # 输出 lib.aa,即:输出模块
    print(obj.__class__) # 输出 lib.aa.C,即:输出类

    3. __init__ 构造方法,通过类创建对象时,自动触发执行。

    4.__del__

     析构方法,当对象在内存中被释放时,自动触发执行。

      注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

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

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

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

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

    8.__getitem__、__setitem__、__delitem__

    用于索引操作,如字典,列表。以上分别表示获取、设置、删除数据;也就是对象后面加[],触发执行

    class Foo(object):
    def __init__(self):
    self.data = {}
    def __getitem__(self, key):
    print('__getitem__', key)
    return self.data.get(key)
    def __setitem__(self, key, value):
    print('__setitem__', key, value)
    self.data[key] =value
    def __delitem__(self, key):
    print('__delitem__', key)
    obj = Foo()
    result = obj['k1'] # 自动触发执行 __getitem__
    obj['k2'] = 'alex' # 自动触发执行 __setitem__
    print(obj['k2']) # 自动触发执行 __getitem__
    print(obj.data)
    del obj['k1'] #自动触发执行 __delitem__


    class Fib(object):
    def __getitem__(self, n):
    a, b = 1, 1
    for x in range(n):
    a, b = b, a + b
    return a
    f = Fib()
    print(f[0])

    说明:对象后面加[],触发执行。

    9. __new__

    class Foo(object):
    def __init__(self, name):
    self.name = name
    print("Foo ---init__")

    def __new__(cls, *args, **kwargs):
    print("Foo --new--")
    print(object.__new__(cls)) #输出<__main__.Foo object at 0x0000000001EA33C8>
    return object.__new__(cls)

    obj = Foo("Alex")
    print(obj) #输出<__main__.Foo object at 0x0000000001EA33C8>

    说明:
    object.__new__(cls) 就是当前实例的内存地址;
    __new__至少要有一个参数cls,代表当前类,也就是Foo
    __new__必须要有返回值,返回实例化出来的实例
    __init__有一个参数self,就是这个__new__返回的实例

    __new__ 是创建实例的,__init__ 是初始化实例的;如果__new__  不return 实例,__init__ 就不能初始化实例,因为__init__中self没有接收到实例;

    10. metaclass

    在Python2.7中,3.x中都可以:

    # metaclass是类的模板,所以必须从`type`类型派生:
    class MyType(type):
    def __init__(self, what, bases=None, dict=None):
    print("--MyType init---")
    super(MyType, self).__init__(what, bases, dict)

    def __call__(self, *args, **kwargs):
    print("--MyType call---")

    obj = self.__new__(self, *args, **kwargs)
    obj.data = {"name":111}

    self.__init__(obj, *args, **kwargs)

    class Foo(object,metaclass = MyType):
    def __init__(self, name):
    self.name = name
    print("Foo ---init__")

    def __new__(cls, *args, **kwargs):
    print("Foo --new--")
    print(object.__new__(cls))
    return object.__new__(cls)

    obj = Foo("Alex")

    返回信息:

    --MyType init---
    --MyType call---
    Foo --new--
    <__main__.Foo object at 0x7f345f5bcc50>
    Foo ---init__

    说明:

    Foo类中写  metaclass = MyType  它指示Python解释器在创建Foo时,要通过MyType.__new__()来创建,在此,我们可以修改类的定义,比如,加上新的方法,然后,返回修改后的定义。
    因为MyType没有重构__new__()这个方法,所以什么都没有执行;在执行__new__()之前先执行__call__,在MyType__call__中定义了如何创建Foo类实例和初始化实例;

    Foo类中__new__, 初始化__init__,__call__都是调用MyType的了;
    __new__这个对象是由__call__ 创建的,所以先执行__call__ 再执行__new_;


    除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass。

    metaclass,直译为元类,简单的解释就是:

    当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。

    但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。

    连接起来就是:先定义metaclass,就可以创建类,最后创建实例。

    所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。

    参考:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319106919344c4ef8b1e04c48778bb45796e0335839000

    11.type

    class Foo(object):

    def __init__(self, name):
    self.name = name


    f = Foo("alex")

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

    #Python中一切事物都是对象。 所以类也是一个对象,Foo类也是一个对象,Foo这个对象就是由type创建出来的;

    用type创建类:
    sex = 'M'
    def func(self):
    print('hello %s' % self.name)

    def cls_init(self, name, age):
    self.name = name
    self.age = age

    Foo = type('class_name', (object,), {'talk': func,
    '__init__': cls_init,'sex':sex})

    #type第一个参数:类名
    #type第二个参数:当前类的基类,不继承要保留()
    #type第三个参数:类的成员

    #{'talk': func,'__init__': cls_init,'sex':sex} 就是talk 这个方法 对应func 这个函数;__init__ 这个这个方法对应cls_init这个函数,这个__init__就是实例初始化的方法,__init__这个名称是固定的;sex 这个类属性对应sex这个变量

    f = Foo("Chrn", 22)
    f.talk()
    print(type(Foo))
    print(f.sex)

     type第二个参数接收的是个元组,注意object后面有个逗号(,) 因为加上逗号是个元组,不加逗号不是个元组,测试代码如下:

    X = ('aa')
    Y = ('bb',)
    print(type(X)) #<class 'str'>
    print(type(Y)) #<class 'tuple'>

    参考:
    https://www.cnblogs.com/alex3714/articles/5213184.html
    https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319098638265527beb24f7840aa97de564ccc7f20f6000
    https://www.cnblogs.com/kex1n/p/5991249.html
  • 相关阅读:
    通用权限管理设计 之 数据库结构设计
    jQuery LigerUI 插件介绍及使用之ligerDateEditor
    jQuery LigerUI 插件介绍及使用之ligerTree
    jQuery LigerUI V1.01(包括API和全部源码) 发布
    jQuery liger ui ligerGrid 打造通用的分页排序查询表格(提供下载)
    jQuery LigerUI V1.1.5 (包括API和全部源码) 发布
    jQuery LigerUI 使用教程表格篇(1)
    jQuery LigerUI V1.0(包括API和全部源码) 发布
    jQuery LigerUI V1.1.0 (包括API和全部源码) 发布
    nginx keepalived
  • 原文地址:https://www.cnblogs.com/lighthouse/p/9673585.html
Copyright © 2011-2022 走看看