zoukankan      html  css  js  c++  java
  • python 类

    1、一般用类自带的__init__函数完成类变量的初始化工作,并且类函数的第一个参数一般都是self,用来表示对象自身,类似于c++对象里面的this指针。并且定义了__init__函数的类就必须按照这个函数参数的形式来构造对象。当然也有特殊的函数,比如说__new__,它的第一个参数是cls,表示类本身,是因为这个函数的作用相当于是用来构造类,而不是对象的。

    2、不像c++,变量必须都要包括在类定义里面,每个类对象可以随时添加变量,当然,这个变量也只属于这个对象,其他对象引用是会出错的。

    3、定义私有变量,是在正常名字前面加上双下划线,就成了私有的,不像c++是通过关键字private来定义的。并且也不是说完全不能访问,是因为解释器把它解释成了别的名字,例如Student类的__name私有变量,直接通过__name是不能访问的,但是用它解释后的名字_Student__name则是可以访问的。

    4、对于带有前双下划线和后双下划綫的变量,这些变量可以在外部访问,但这些是特殊变量,自己定义的变量不要写成这种形式。

    5、前面带有单下划线的变量,也可以在外部访问,但一般也把它们当做私有变量不要去访问它。

    6、使用dir(对象名)函数可以得到这个对象所属类型的所有可用函数和变量

    类的集成与派生

    1、在派生类,只需要重写基类的函数,函数声明一致,就自动与基类同名函数互为虚函数,假定函数形参是基类类型,如果给一个基类的实参,就调用基类的函数,如果给的是继承类的对象,就调用继承类的函数。当然如果继承类没有重写函数,都会调用基类的函数。

    2、如果类没有直接的基类,就让它继承系统的object类,从这样看,所有的类的基类都是object。

    3、判断某个变量是否是某个类型可用isinstance判断,会返回True或False,并且在判断类对象时,只要类型名是该对象的类或该类的基类,返回值都是True,用法为:

    isinstance(变量名,类型名)

    4、判断某个对象的类型可用type()判断,会直接返回类型名,用法为

    type(对象名)

    5、有了上面判断对象的类型,也有判断判断对象中是否含有某属性的方法,常用的方法有以下三个:

    hasattr(对象名,属性变量名)#判断对象中是否含有某变量,这个方法在构造单例时非常有用

    getattr(对象名,属性变量,默认值)#获取指定属性的值,如果属性不存在,就返回默认值

    setattr(对象名,属性变量,设定值)#设置指定属性的值

    高级特性

    __slots__

    1、类对象可以动态添加自己的属性,如果要限制变量的名字,就可以使用这个属性,讲一个元组赋给它,这样就只能添加元组里每个元素指定变量名

    2、该属性只对当前类起作用,如果继承类没使用该属性,就不会继承该特性,使用了就会继承。

    类自带的特殊方法

    __str__()和__repr__():类对象的输出处理函数,类似于c++中的cout重载

    __iter__
    如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
    我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:

    class Fib(object):
         def __init__(self):
             self.a, self.b = 0, 1 # 初始化两个计数器a,b
    
        def __iter__(self):
            return self # 实例本身就是迭代对象,故返回自己
    
        def next(self):
            self.a, self.b = self.b, self.a + self.b # 计算下一个值
            if self.a > 100000: # 退出循环的条件
                raise StopIteration();
            return self.a # 返回下一个值                

    __getitem__

    可以像列表那样用索引来去除第几个元素

    __getattr__()

    用于动态返回一个属性

    type()
    动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。
    比方说我们要定义一个Hello的class,就写一个hello.py模块:

    class Hello(object):
        def hello(self, name='world'):
            print('Hello, %s.' % name)    

    当Python解释器载入hello模块时,就会依次执行该模块的所有语句,执行结果就是动态创建出一个Hello的class对象,测试如下:

    >>> from hello import Hello
    >>> h = Hello()
    >>> h.hello()
    Hello, world.
    >>> print(type(Hello))
    <type 'type'>
    >>> print(type(h))
    <class 'hello.Hello'>

    type()函数可以查看一个类型或变量的类型,Hello是一个class,它的类型就是type,而h是一个实例,它的类型就是class Hello。
    我们说class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。
    type()函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过type()函数创建出Hello类,而无需通过class Hello(object)...的定义:

    >>> def fn(self, name='world'): # 先定义函数
    ... print('Hello, %s.' % name)
    ...
    >>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello
    class
    >>> h = Hello()
    >>> h.hello()
    Hello, world.
    >>> print(type(Hello))
    <type 'type'>
    >>> print(type(h))
    <class '__main__.Hello'>

    要创建一个class对象,type()函数依次传入3个参数:
    1. class的名称;
    2. 继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的
    单元素写法;
    3. class的方法名称与函数绑定,这里我们把函数fn 绑定到方法名hello上。
    通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class。
    正常情况下,我们都用class Xxx...来定义类,但是,type()函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。


    metaclass
    除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass。metaclass,直译为元类,简单的解释就是:当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。
    但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。
    连接起来就是:先定义metaclass,就可以创建类,最后创建实例。
    所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。

  • 相关阅读:
    Luogu P1004 方格取数
    Luogu P1896 [SCOI2005]互不侵犯
    Luogu P1879 [USACO06NOV]玉米田Corn Fields 【状压dp模板】
    高精度模板(结构体)
    【模板】快读
    vue input框type=number 保留两位小数自定义组件
    elementui表格表头合并
    将excle表中得数据生成insert语句插入到数据库中
    数据库基本语法
    ztree 数组和树结构互转算法
  • 原文地址:https://www.cnblogs.com/suntp/p/6491865.html
Copyright © 2011-2022 走看看