• python类内init外声明的属性与init内声明的对象属性的访问和操作区别


    python类内init外声明的属性与init内声明的对象属性的访问和操作区别(面试题) 

     1.在ipython中输入以下代码,其输出会是什么?

    In [1]: class ClassOut:
       ...:     out_mem = 'out_mem'
       ...:     print out_mem
       ...:     def __init__(self):
       ...:         inner_mem = 'inner_mem'
       ...:         self.inner_mem = 'self.inner_mem'
       ...:         self._inner_mem = 'self._inner_mem'
       ...:         self.out_mem = 'self.out_mem' 
       ...:     
    
    
    In [2]: out = ClassOut()
    
    In [3]: out.out_mem
    
    
    In [4]: out._inner_mem
    
    
    In [5]: out.inner_mem
    
    
    In [6]: class ClassOut:
       ...:     out_mem = 'out_mem'
       ...:     print out_mem
       ...:     def __init__(self):
       ...:         inner_mem = 'inner_mem'
       ...:         self.inner_mem = 'self.inner_mem'
       ...:         self._inner_mem = 'self._inner_mem'
       ...:         self.out_mem1 = 'self.out_mem1'
       ...:         
    out_mem
    
    In [7]: out = ClassOut()
    
    In [8]: out.out_mem
    
    
    In [9]: ClassOut.out_mem
    
    
    In [10]: ClassOut.out_mem1
    
    In [11]: out._inner_mem
    
    
    In [12]: out.out_mem = 'out_mem modified by object'
    
    In [13]: ClassOut.out_mem
    
    
    In [14]: out.out_mem
    
    
    In [15]: out.new_mem = 'clas'
    
    In [16]: out.new_mem
    
    
    In [17]: o = ClassOut()
    
    In [18]: o.out_mem
    
    
    In [19]: ClassOut.out_mem
    
    
    In [20]: ClassOut.out_mem = 'out_mem modified by Class'
    
    In [21]: o.out_mem

     考察:

    1. python解释器处理解释class

    2. 类的初始化定义方法

    3. 类的__init__方法 与 class object成员定义, class instance成员的定义

    4. 类定义成员时的命名约定

    5. class object  与 class instance的区别

    6. class object 与 class instance在处理缺失成员访问时查询域优先级的区别

    7. class 定义 __private_mem 不被外部发现的元婴? (被重命名为_[class_name]__private_mem)!!!详见如下代码!

    In [48]: class ClassOut:

        ...: out_mem = 'out_mem'

        ...: print out_mem

        ...: def __init__(self):

        ...: inner_mem = 'inner_mem'

        ...: self.inner_mem = 'self.inner_mem'

        ...: self._inner_mem = 'self._inner_mem'

        ...: self.out_mem1 = 'self.out_mem1'

        ...: self.__private_mem = 'self.__private_mem'

        ...:

    out_mem

    In [49]: no = ClassOut()

    In [50]: no.__private_mem

    ---------------------------------------------------------------------------

    AttributeError Traceback (most recent call last)

    <ipython-input-50-36dd351a1b65> in <module>()

    ----> 1no.__private_mem

    AttributeError: ClassOut instance has no attribute '__private_mem'

    In [51]: no._ClassOut__private_mem

    Out[51]: 'self.__private_mem'

    8.1. 不能直接给对象设置属性?

    >>> obj = object()
    >>> obj.name = "whatever"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'object' object has no attribute 'name'
    

    但是为什么这样就可以呢:

    >>> class Object(object):pass
    ...
    >>> Obj = Object()
    >>> Obj.name = "whatever"
    >>> Obj.name
    'whatever'
    >>>
    

    答: 现在你给第二个代码块中的Object加上属性 __slots__ 试试:

    >>> class Object(object):
    ...     __slots__ = {}
    ...
    >>> Obj = Object()
    >>> Obj.name = "whatever"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'Object' object has no attribute 'name'
    

    会发现抛出了同样的异常。 object 、 list 、 dict 等内置函数都如此。

    拥有 __slots__ 属性的类在实例化对象时不会自动分配 __dict__ ,而obj.attr 即 obj.__dict__['attr'], 所以会引起 AttributeError

    对于拥有 __slots__ 属性的类的实例 Obj 来说,只能对 Obj 设置__slots__ 中有的属性:

    >>> class Object(object):
    ...     __slots__ = {"a","b"}
    ...
    >>> Obj = Object()
    >>> Obj.a = 1
    >>> Obj.a
    1
    >>> Obj.c = 1
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'Object' object has no attribute 'c'
    

    详细见 Python-slots-doc

  • 相关阅读:
    Notepad++编译和运行Java
    Notepad++ 代码格式化插件
    使用electron构建跨平台Node.js桌面应用经验分享
    如何在64位WIN7下安装64位的解压版mysql-5.6.37-winx64.zip
    排序算法之冒泡排序的思想以及Java实现
    centos7.1部署java环境服务器
    Hadoop化繁为简-从安装Linux到搭建集群环境
    零基础搭建 spring mvc 4 项目(本文基于 Servlet 3.0)
    关闭Eclipse按空格和等号键自动补全内容
    新一代服务器性能测试工具Gatling
  • 原文地址:https://www.cnblogs.com/ToDoToTry/p/3658429.html
Copyright © 2020-2023  润新知