python类的定义以及__dict__和__new()__作用
python类的定义以及__dict__和__new()__作用
1.类的定义
定义一个类可以用下面三种方法:
#Classes without an inheritance list inherit, by default, from the base class object
#1.默认继承object
class Foo:
pass
#2.
class Foo():
pass
#3可以继承多个class,用逗号分开即可
class Foo(object):
pass
定义完类,可以生成一个对象,可以动态给对象添加属性。
ff = Foo() ff.cls_name = Foo
其实也可以给类动态添加属性。因为其实类本身也是type的一个对象。
>>> Foo <class __main__.Foo> >>> Foo.cls_name = FooCls >>>
无论是类还是对象,都有一个__dict__字段(属性)。该字段保存着该类或者对象的属性信息。但是对象的__dict__只保存该对象特有的信息。看下面例子:
class Foo:
#name is a class attribute
cls_name = a Foo cls
>>> ff = Foo()
>>> ff.obj_name = a Foo obj
>>> ff.__dict__
{
obj_name: a Foo obj}
# 给对象ff添加一个object method
>>> ff.fun = abs
>>> ff.__dict__
{
obj_name: a Foo obj, fun: <built-in function abs>}
2. __new()__方法的使用
在定义一个类的时候,一般要写一个__init__(self[, …])方法来进行初始化。但是Python解释器在调用__init__前,必须先调用__new()来生成一个该类的对象(注意:return an instance of cls)。如果当前类没有定义,那么会执行父类的__new()。__new()__方法有如下特性:
- is a static method,special-cased so you need not declare it as such.
- takes the class of which an instance was requested as its first argument
- The remaining arguments are those passed to the object constructor expression (the call to the class).()
- If new() does not return an instance of cls, then the new instance’s init() method will not be invoked.
- 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().
- 通过是__new__()的第一参数cls,结合cls.__dict__属性,可以动态修改当前类或者子类的类属性。
class Animal(object):
def __init__(self):
pass
def __new__(cls, *args, **kw):
print(cls, args, kw)
return super().__new__(cls)
class Cat(Animal):
def __init__(self, name, weight):
self.name = name
self.weight = weight
acat = Cat(huahua, 30)
>>> acat = Cat(huahua, 30)
<class __main__.Cat> (huahua, 30) {
}
需要注意的是__new__()和__init__()的除了第一个参数外,要一致,否则会出现错误提示。因为python解释器在生成一个对象的时候,比如执行 acat = Cat(‘huahua’, 30),会进行两部操作:
- 把参数列表 cls, ‘huahua’, 30传给 __new()__函数,得到一个对象实例object
- 把参数列表 object, ‘huahua’, 30传给 __init()__函数,进行初始化
>>> class Dog(): ... def __init__(self): ... self.name = dog ... def __new__(cls, a): ... print(cls, a) ... return super().__new__(cls) ... >>> adog = Dog(20) <class __main__.Dog> 20 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() takes 1 positional argument but 2 were give >>> adog = Dog() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __new__() missing 1 required positional argument: a
一般情况下__new__()方法的作用就是把第一个参数cls(当前类的定义)传给父类,然后返回一个该类对象。我们也可以在这个过程中进行修改,或者直接让__new__()返回一个对象。
class Cat():
pass
class Dog():
name = my name is dog.
def __new__(cls):
print(cls)
return Cat()
>>> a = Dog()
<class __main__.Dog>
>>> a
<__main__.Cat object at 0x013E3B50>
