zoukankan      html  css  js  c++  java
  • 符合python风格的对象

    image-20200407123042829

    image-20200407123103257

    ❶ klassmeth 返回全部位置参数。 ❷ statmeth 也是。 ❸ 不管怎样调用 Demo.klassmeth, 它的第一个参数始终是 Demo 类。 ❹ Demo.statmeth 的行为与普通的函数相似。

    classmethod 装饰器非常有用, 但是我从未见过不得不用staticmethod 的情况。 如果想定义不需要与类交互的函数, 那么在模块中定义就好了。

    可散列的vector

    按照定义, 目前 Vector2d 实例是不可散列的, 因此不能放入集合
    (set) 中:
    >>> v1 = Vector2d(3, 4)
    >>> hash(v1)
    Traceback (most recent call last):
    ...
    TypeError: unhashable type: 'Vector2d'
    >>> set([v1])
    Traceback (most recent call last):
    ...
    TypeError: unhashable type: 'Vector2d'
    为了把 Vector2d 实例变成可散列的, 必须使用 __hash__ 方法(还需
    __eq__ 方法, 前面已经实现了) 此外, 还要让向量不可变, 详情
    参见第 3 章的附注栏“什么是可散列的数据类型”。
    目前, 我们可以为分量赋新值, v1.x = 7Vector2d 类的代码并
    不阻止这么做。 我们想要的行为是这样的:
    >>> v1.x, v1.y
    (3.0, 4.0)
    >>> v1.x = 7
    Traceback (most recent call last):
    ...
    AttributeError: can't set attribute
    为此, 我们要把 x y 分量设为只读特性, 如示例 9-7 所示。
    示例 9-7 vector2d_v3.py: 这里只给出了让 Vector2d 不可变的代
    码, 完整的代码清单在示例 9-9
    class Vector2d:
       typecode = 'd'
       def __init__(self, x, y):
           self.__x = float(x) ➊self.__y = float(y)
       @property
       def x(self):
           return self.__x
       @property
       def y(self):
           return self.__y
       def __iter__(self):
           return (i for i in (self.x, self.y))
    # 下面是其他方法(排版需要, 省略了)
    使用两个前导下划线(尾部没有下划线, 或者有一个下划线)
    属性标记为私有的。
    根据本章开头引用的那句话, 这不符合 Ian Bicking 的建议。 私有属性的优缺点参见后面的 9.7
    节。
    @property 装饰器把读值方法标记为特性。
    读值方法与公开属性同名, 都是 x。
    直接返回 self.__x。
    以同样的方式处理 y 特性。
    需要读取 x y 分量的方法可以保持不变, 通过 self.x self.y
    读取公开特性, 而不必读取私有属性, 因此上述代码清单省略了这个类
    的其他代码。

    然后重写hash

    # 在Vector2d类中定义
    def __hash__(self):
    return hash(self.x) ^ hash(self.y)
    添加 __hash__ 方法之后, 向量变成可散列的了:
    >>> v1 = Vector2d(3, 4)
    >>> v2 = Vector2d(3.1, 4.2)
    >>> hash(v1), hash(v2)
    (7, 384307168202284039)
    >>> set([v1, v2])
    {Vector2d(3.1, 4.2), Vector2d(3.0, 4.0)}

    Python的私有属性和“受保护的”属性

    python 不像java 可以用private定义私有属性++

    但是Python 有个简单的机制, 能避免子类意外覆盖“私有”属性。 举个例子。 有人编写了一个名为 Dog 的类, 这个类的内部用到了 mood 实例属性, 但是没有将其开放。 现在, 你创建了 Dog 类的子 类: Beagle。 如果你在毫不知情的情况下又创建了名为 mood 的实例属 性, 那么在继承的方法中就会把 Dog 类的 mood 属性覆盖掉。 这是个难 以调试的问题。

    为了避免这种情况, 如果以 __ mood 的形式(两个前导下划线, 尾部没 有或最多有一个下划线) 命名实例属性, Python 会把属性名存入实例的 _ dict__ 属性中, 而且会在前面加上一个下划线和类名。 因此, 对 Dog 类来说, __ mood 会变成 _ Dog __ mood; 对 Beagle 类来说, 会变成 _Beagle__mood。 这个语言特性叫名称改写

    类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在dict里的

    总结:

      1) 内置的数据类型没有 __ dict__属性

      2) 每个类有自己的 __ dict属性,就算存着继承关系,父类的 dict__ 并不会影响子类的__ dict__

      3) 对象也有自己的__ dict属性, 存储self.xxx 信息,父子类对象公用 dict__

    image-20200407134334457

    image-20200407134501701

    slots 的问题 总之, 如果使用得当, slots 能显著节省内存, 不过有几点要注 意。 每个子类都要定义 slots 属性, 因为解释器会忽略继承的 slots 属性。 实例只能拥有 slots 中列出的属性, 除非把 'dict' 加 slots 中(这样做就失去了节省内存的功效) 。 如果不把 'weakref' 加入 slots, 实例就不能作为弱引 用的目标。

    抽象方法使用 @abstractmethod 装饰器标记

     

  • 相关阅读:
    改进的二分查找
    关于Java并发编程的总结和思考
    java异常捕获案例,此题的出处是《Java编程思想》一书
    一道关于int和Integer的面试题
    看《韩顺平Java》视频的笔记
    spring task 定时任务执行两次
    记录
    Java基础面试题
    TeamViewer修改绑定设备
    jqGrid常用操作
  • 原文地址:https://www.cnblogs.com/handso/p/13729694.html
Copyright © 2011-2022 走看看