python类的实例方法必须在创建对象前调用,关于对象:为什么Python在实例创建时调用实例方法__init __()而不是调用类提供的__init __()?...

我重写了类的__new__()方法以返回具有特定__init__()集的类实例。虽然python文档位于

http://docs.python.org/reference/datamodel.html网站

说:

Typical implementations create a new instance of the class by invoking the

superclass’s __new__() method using super(currentclass, cls).__new__(cls[, ...])

with appropriate arguments and then modifying the newly-created instance as

necessary before returning it.

If __new__() returns an instance of cls, then the new instance’s __init__() method

will be invoked like __init__(self[, ...]), where self is the new instance and the

remaining arguments are the same as were passed to __new__().

这是我的测试代码:

#!/usr/bin/env python

import new

def myinit(self, *args, **kwargs):

print"myinit called, args = %s, kwargs = %s" % (args, kwargs)

class myclass(object):

def __new__(cls, *args, **kwargs):

ret = object.__new__(cls)

ret.__init__ = new.instancemethod(myinit, ret, cls)

return ret

def __init__(self, *args, **kwargs):

print"myclass.__init__ called, self.__init__ is %s" % self.__init__

self.__init__(*args, **kwargs)

a = myclass()

哪些输出

$ python --version

Python 2.6.6

$ ./mytest.py

myclass.__init__ called, self.__init__ is >

myinit called, args = (), kwargs = {}

看来让myinit()运行的唯一方法,就是在myclass.__init__()内部明确地称为self.__init__()。

好问题!

新样式类上的特殊方法是在实例的类型上查找的,而不是在实例本身上查找的。这是记录在案的行为:

For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary. That behaviour is the reason why the following code raises an exception (unlike the equivalent example with old-style classes):

>>> class C(object):

...     pass

...

>>> c = C()

>>> c.__len__ = lambda: 5

>>> len(c)

Traceback (most recent call last):

File"", line 1, in

TypeError: object of type 'C' has no len()

各种特殊方法(包括__init__,也包括运算符重载,如__add__等)总是通过类而不是实例访问。不仅如此,它们不能通过类或元类上的__getattr__或__getattribute__方法访问,它们必须直接在类上。这是为了提高效率:

Bypassing the __getattribute__() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter).

目前还不完全清楚您试图完成什么,但您可以在这里做的一件事是在__new__方法中对myclass进行子类划分:

class myclass(object):

def __new__(cls, *args, **kwargs):

class subcls(cls):

def __new__(cls, *args, **kwargs):

return object.__new__(cls)

subcls.__init__ = myinit

return subcls(*args, **kwargs)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值