python类的定义以及__dict__和__new()__作用
程序员文章站
2024-03-26 10:02:17
...
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>
上一篇: python中函数的定义和调用注意事项
下一篇: 高阶函数-懂了你就进入升华了
推荐阅读
-
python类的定义以及__dict__和__new()__作用
-
python : 自定义可迭代类,__iter__ ,__next__的作用
-
Python面向对象中的类方法,静态方法以及私有属性和私有方法
-
理解java和python类变量以及类的成员变量
-
理解java和python类变量以及类的成员变量
-
友元函数的定义位置,以及模板类声明和定义位置 - 编译过程理解(如何避免undefined错误)
-
Python函数作用域和匿名函数以及闭包、回调、递归的使用
-
Python自定义类中内部函数:__repr__()和__string__()的应用
-
从7点到9点写的小程序(用了模块导入,python终端颜色显示,用了点局部和全局可变和不可变作用域,模块全是自定义)
-
Python和Lua的默认作用域以及闭包