快捷搜索: 王者荣耀 脱发

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()__方法有如下特性:

  1. is a static method,special-cased so you need not declare it as such.
  2. takes the class of which an instance was requested as its first argument
  3. The remaining arguments are those passed to the object constructor expression (the call to the class).()
  4. If new() does not return an instance of cls, then the new instance’s init() method will not be invoked.
  5. 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().
  6. 通过是__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),会进行两部操作:

  1. 把参数列表 cls, ‘huahua’, 30传给 __new()__函数,得到一个对象实例object
  2. 把参数列表 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>
经验分享 程序员 微信小程序 职场和发展