擅长:python、mysql、java
<p>下面是我能想到的使这件事变得危险的事情的清单,大致顺序是从最坏到最坏:</p>
<ul>
<li>这可能会让阅读或调试代码的人感到困惑。</li>
<li>您不会得到正确的<code>__init__</code>方法,因此您可能不会正确初始化所有实例变量(甚至根本不会)。</li>
<li>2.x和3.x之间的差异非常显著,可能会导致移植疼痛。</li>
<li>类方法、手工编码的描述符、方法解析顺序的钩子等等都有一些边缘情况,它们在经典类和新样式类之间是不同的(同样,在2.x和3.x之间也是不同的)。</li>
<li>如果使用<code>__slots__</code>,则所有类都必须具有相同的插槽。(如果你有兼容的但不同的插槽,它可能一开始看起来工作,但做了可怕的事情…)</li>
<li>新样式类中的特殊方法定义可能不会更改。(事实上,这将在所有当前Python实现的实践中工作,但是没有<em>文档</em>来工作,所以…)</li>
<li>如果您使用<code>__new__</code>,事情就不会像您天真地期望的那样工作。</li>
<li>如果类有不同的元类,事情会变得更加混乱。</li>
</ul>
<p>同时,在许多情况下,如果你认为这是必要的,还有更好的选择:</p>
<ul>
<li>使用工厂动态地创建适当类的实例,而不是创建一个基本实例,然后将其转换为派生实例。</li>
<li>使用<code>__new__</code>或其他机制挂接构造。</li>
<li>重新设计一些东西,这样就有了一个具有数据驱动行为的类,而不是滥用继承。</li>
</ul>
<p>作为上一个非常常见的特定情况,只需将所有“变量方法”放入其实例作为“父”的数据成员保存的类中,而不是放入子类中。不要改变<code>self.__class__ = OtherSubclass</code>,只要做<code>self.member = OtherSubclass(self)</code>。如果您真的需要神奇地更改方法,那么自动转发(例如,通过<code>__getattr__</code>)是一个比动态更改类更常见的python习惯用法。</p>