• [python] 之 类编码细节


    1. class语句创建类

    class()语句是对象的创建者并且是一个隐含的赋值运算-执行时,它会创建对象,并把引用值存储在前面所使用的变量名,这一点和函数def语句一样,语法定义如下。

    1 class <name>(superclass, ... ):       #asssign to name 
    2     data = value  #shared class data
    3     def method(self, ...): #methods
    4         sself.member = value #Per-instance data

    注:在类中,所有顶层的赋值语句,一般都可以看作是类的属性,可以供所有由给类创建的实例所共享。类和实例都有着自己的命名空间或作用域,且所有类的属性都可以被其创建的实例所共享。而各个实例虽然来自于同一个类所创建,但是它们有着封闭的独立命名空间,互不干扰。若更改类的属性,会影响所有的实例,但如果只更改某一个实例的属性,不会影响其它的实例和创建该实例的类;在python当中,一般函数,类,模块能够创建作用域,封闭变量名。

     1 class P(object):
     2     spam = 88
     3     
     4 x1 = P()
     5 x2 = P()
     6 print (P.spam,x1.spam,x2.spam)
     7 print ('P.__dict__:',P.__dict__)
     8 print ('x1.__dict__:',x1.__dict__)
     9 print ('x2.__dict__:',x2.__dict__)
    10 
    11 P.spam = 99
    12 print (P.spam,x1.spam,x2.spam)
    13 print ('P.__dict__:',P.__dict__)
    14 print ('x1.__dict__:',x1.__dict__)
    15 print ('x2.__dict__:',x2.__dict__)
    16 
    17 x1.spam = 66
    18 print (P.spam,x1.spam,x2.spam)
    19 print ('P.__dict__:',P.__dict__)
    20 print ('x1.__dict__:',x1.__dict__)
    21 print ('x2.__dict__:',x2.__dict__)
    22 #输出
    23 88 88 88
    24 P.__dict__: {'__weakref__': <attribute '__weakref__' of 'P' objects>, '__module__': '__main__', 'spam': 88, '__dict__': <attribute '__dict__' of 'P' objects>, '__doc__': None}
    25 x1.__dict__: {}
    26 x2.__dict__: {}
    27 99 99 99
    28 P.__dict__: {'__weakref__': <attribute '__weakref__' of 'P' objects>, '__module__': '__main__', 'spam': 99, '__dict__': <attribute '__dict__' of 'P' objects>, '__doc__': None}
    29 x1.__dict__: {}
    30 x2.__dict__: {}
    31 99 66 99
    32 P.__dict__: {'__weakref__': <attribute '__weakref__' of 'P' objects>, '__module__': '__main__', 'spam': 99, '__dict__': <attribute '__dict__' of 'P' objects>, '__doc__': None}
    33 x1.__dict__: {'spam': 66}
    34 x2.__dict__: {}

    2. 方法

      方法通过实例或类本身两种方法其中的任意一种进行调用。

      self明确化的意义:明确脚本中使用的是实例属性名称,而不是本地作用域或全局作用域。

      通过类调用方法的模式,是扩展继承方法行为的一般基础,但一定要为方法传入实例。

      instance.method(args) <=> class.method(instance, args)

    3. 调用超类构造函数

      通过类调用方法一定要为类提供实例

    4. 继承

      继承 ---》 定制 ---》 扩展

       属性树的构建:

      1》实例属性是由对方法内self属性进行赋值运算而生成的

      2》类属性是通过class语句内的顶层赋值语句赋值而生成的

      3》属性树的搜索顺序在2.2版本以后都采用了广度优先的搜索算法;经典类采用深度优先算法,从左至右;新式类采用广度优先搜索。

    6. 继承方法的专有化

       命名空间或作用域的专有化,只能由创建它们的类或实例调用。

    7. 命名空间-完整内容

      在python中,创建命名空间的功能语句只有def,class,model。

     7.1 变量名有无点号的区别

      1》无点号运算的变量名(例如,X)与作用域对应

      2》点号的属性名使用(object.X)的是对象(object)的命名空间

     7.2 简单变量名:如果赋值就不是全局变量

       无点号的简单变量名遵循LEGB法则

       1》赋值语句(X=value)

        使变量名变为本地变量:在当前作用域内,创建或改变变量名X,除非声明是全局变量

       2》引用(X)

        在当前作用域内搜索变量名(X),之后是在任何以及所有的嵌套的函数中,然后是在当前的全局作用域中搜索,最后在内置作用域中搜索。

     7.3 属性名称:对象命名空间

       点号的属性名指的是特定对象的属性,并遵循模块和类的规则,引用增加了继承搜索规则。

       1》赋值语句(object.X = value)

        在进行点号运算的对象的命名空间内创建或修改属性名X

       2》引用(object.X)

        基于类的对象,在对象内搜索属性名,然后是其上所有可读取的类(使用继承搜索流程);

        基于模块的对象,从对象中直接读取。

      注:作用域总是由源代码中的赋值语句位置决定的(也就是语句),而绝不会受到其导入关系的影响;创建实例属性的方法是在类的__init__构造函数内进行赋值的,但并不是唯一的,只要进行了self赋值运算都创建实例属性。典型例子如下:

     1 #manyneme.py
     2 x = 11                # ①.模块属性
     3 
     4 def f():
     5     print x
     6 
     7 def g():
     8     x = 22            # ②.函数内的本地变量
     9     print x
    10 
    11 class C:
    12     x = 33            # ③.类属性
    13     def m(self):
    14         x = 44        # ④.方法中的本地变量
    15         self.x = 55   # ⑤.实例属性

    8. 命名空间字典

     object.__dict__:只显示object对象的命名空间字典,不包含继承的命名空间字典。

     dir(object):显示object对象本身的命名空间字典和继承的命名空间字典。

    9. 文档字符串

      下面以一个例子说明文档字符串出现的位置(这些位置的文档字符串可以通过object.__doc__访问)

     

     1 #docstr.py
     2 "I am: docstr.__doc__"
     3 
     4 def func(args):
     5     "I am: docstr.func.__doc__ "
     6     pass
     7 
     8 class P(object):
     9     "I am: docstr.P.__doc__ or P.__doc__ "
    10     def method(self):
    11         "I am: P.method.__doc__ or self.method__doc__"

    10. 类与模块的关系

      模块:

        是数据或逻辑包

        通过python文件或C扩展创建

        通过导入来使用

      类:

        实现新的对象

        由class语句创建

        通过调用使用

        总是位于一个模块中

  • 相关阅读:
    ~~网络编程(六):自定义报头~~
    ~~网络编程(五):粘包现象~~
    ~~网络编程(四):socket套接字~~
    ~~网络编程(三):TCP/UDP~~
    ~~网络编程(二):层级初识~~
    Java的异常处理方式
    Java中的泛型
    Collection接口综述
    匿名内部类和局部内部类只能访问final变量的原因
    Java内部类
  • 原文地址:https://www.cnblogs.com/xiaofeiIDO/p/6028398.html
Copyright © 2020-2023  润新知