正文
Foo
(
object
):
def
__new__
(
cls
,
*
args
):
return
cls
# 我们不返回实例了,直接返回类
def
__init__
(
self
,
*
args
):
self
.
name
=
'the5fire'
foo
=
Foo
()
print
(
foo
)
# -->
这种情况下得到的是Foo这个类,而不是实例。因此我们可以通过在
__new__
这个方法里折腾点东西。
这里总结下,
__new__
是来控制类创建的,而
__init__
是来控制实例初始化的。
理解type
再来看type的使用,the5fire之前写的那篇
《Django分表的两个方案》
有说到怎么使用type动态创建类。可以通过这案例理解type的使用。而这里的type.
new
是类似的,我们在ipython中看下这俩函数的说明:
In [3]: type?
Docstring:
type(object) -> the object's type
type(name, bases, dict) -> a new type
Type: type
In [4]: type.__new__?
Docstring: T.__new__(S, ...) -> a new object with type S, a subtype of T
Type: builtin_function_or_method
type(name, bases, dict)
返回一个新的类型,继承自传递进入的bases(这个参数必须是tuple类型),以及拥有dict参数中定义的属性。
type.__new__(S, ...)
返回一个S类型的新对象,注意,这个新对象并不是我们平时写代码中的类的实例,而是类。因为S必须是type的子类(继承自type)。
我们还是来通过代码认识下:
# 1. 通过type创建类
def class_creator(name):
return type(name, (), {})
Person = class_creator('Person')
print(Person, type(Person)) # --> (, )
# 2. 通过type.__new__创建类
def class_creator(name):
return
type.__new__(type, name, (), {})
Person = class_creator('Person')
print(Person, type(Person)) # --> (, )
# 3. 通过type.__new__创建一个自定义的类
class CustomClass(type):
def __new__(cls, name, bases, attrs):
print('in CustomClass')
return type.__new__(cls, name, bases, attrs)
def class_creator(name):
return type.__new__(CustomClass, name, (), {})
Person = class_creator('Person')
print(Person, type(Person)) # --> (, )
把上面代码放到本地,运行下试试。
其中[3]里面定义了
CustomClass.__new__
,你运行过上面代码后发现并没有print出来"in CustomClass"的结果。这意味着通过
type.__new__
创建的
CustomClass
的实例,并没有执行
__new__
这个方法。