zoukankan      html  css  js  c++  java
  • Python 中的属性覆盖和猴子补丁

    一般说,在基类中定义的访问基类中属性的方法,即使派生类覆盖他也不会造成影响,没懂?

    我的意思是这个 举一个简单的例子

    public class Person {
        private final String _name = "person";
    
        public String getName() {
            return this._name;
        }
    }
    
    public class Worker extends Person {
        private final String _name = "worker";
    }
    

    你应该不会疑惑当我实例化 Worker 类然后再在调用 getName 方法应该返回的是 person 吧。

    但是在 py 中就不不是这样,例如:

    class Person:
      def __init__(self):
        self._name = 'person'
      
      def get_name(self):
        return self._name
    
    class Worker(Person):
      def __init__(self):
        self._name = 'worker'
    
    # >>> w = Worker()
    # >>> w.get_name()
    # 'worker'
    

    不仅是对象属性会表现出这样的特点,对于类属性(或者如果按java的叫法应该叫做静态属性)也会如此。

    所以假如你在代码中做了这样的事情的话,可能会出现奇怪的问题,假使你重来没有遇到过这种问题,也算正常,毕竟在父子类中起一个重复的变量名好像没有什么特别的好处,也算不上好实践

    PS;好像需要收回这句话,Django源码中经常这样做,并且在利用行为

    那么接下来在来看一下猴子补丁还是以上面定义的 py 代码为例:

    def get_name(self):
      return 'new name'
    
    Worker.get_name = get_name # 用 Person.get_name = get_name 也是一样滴~~
    w.get_name
    # >>> 'new name'
    

    运行时改变行为,这个就叫猴子补丁

    当然还有就是这边直接修改的时未绑定方法,如果修改绑定方法的话,那么就不需要 self 参数了,如

    def get_name():
      return 'foo'
    
    w.get_name = get_name
    w.get_name()
    # >>> 'foo'
    

    啥叫绑定(bind),啥叫未绑定呢?

    可以注意到在类中定义的成员方法时候都需要传递一个 self 参数,然而在对象实例话以后成员函数的 self 参数却又不需要传递了,也就是说该对象的成员函数中的 self 参数和该对象绑定了

    PS: 了解一点JS的可能觉得也不算太奇怪,因为 JS 就有 call、apply 和 bind 函数,略略略

    而在类中,他们还是尚未绑定的,例如我们可以这样调用尚未绑定的方法

    Person.get_name(w)
    # >>> 'worker'
    
  • 相关阅读:
    Silverlight Toolkit ListBoxDragDropTarget学习笔记
    函数指针和指针函数(转)
    面试题_反转链表
    C++中的异或运算符^
    面试题_旋转字符串
    面试题_寻找丑数
    模拟一个简单的基于tcp的远程关机程序
    管理指针成员
    赫夫曼树编码问题
    堆的基本操作
  • 原文地址:https://www.cnblogs.com/freesfu/p/15695109.html
Copyright © 2011-2022 走看看