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>