在前面已经介绍过__init__,__base__,__bases__,__mro__等特殊属性,这节继续讲解一些特殊的类的属性方法。

__new__()

是在创建对象时调用,用于对象创建。

1
2
3
4
5
6
class Dog:
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')

d = Dog()  #结果是输出 '创建对象'

__new__和__init__的不同
类创建对象时,若类中定义了__init__方法,但没定义__new__方法,会自动调用父类object的__new__方法通过系统的方式创建对象,对象一创建完会自动调用类中定义的__init__方法。

(1)__new__方法是在创建对象时调用的;__init__方法是在对象一创建完就调用,而且只有通过系统的方法创建的对象才会执行__init__方法,object默认的__new__方法会先于__init__方法调用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Dog:
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')
        return '1'  #没有按照系统的方式创建对象,而是直接返回整数1

    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')
dog1 = Dog()
print(dog1)

执行以上程序会输出如下结果:

1
2
创建对象
1

因为不是按照系统的方式创建对象,所以就不会调用__init__方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Dog:
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')
        #返回默认的父类object通过\_\_new\_\_方法创建的对象,即通过系统的方式创建的对象
        return object.__new__(cls)
    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')
dog1 = Dog()
print(dog1)

执行以上程序会输出如下结果:

1
2
3
创建对象
对象初始化
<__main__.Dog object at 0x000000000290B898>

(2)__new__方法的形参是类,而__init__方法的形参是对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Dog:
    __type = '狗' #类属性
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')
        #会将返回值提供给引用对象变量
        return cls.__type

    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')

dog1 = Dog()
print(dog1)

执行以上程序会输出如下结果:

1
2
创建对象

析构函数__del__()

__init__()在对象被创建的时候进行调用,成为初始化函数。而对象被销毁的时候就会调用__del__()函数,成为析构函数。

1
2
3
4
5
6
class Car:
    def __init__(self):
        print('我被创建了')
    def __del__(self):
        print('我要被销毁了')
c1=Car()

执行以上程序会输出如下结果:

1
2
我被创建了
我要被销毁了

class.__call__()

当对象作为一个函数进行执行的时候,就会执行这个方法。

1
2
3
4
5
class Car:
    def __call__(self, *args, **kwargs):
        print("Car's call")
c1=Car()
c1() #运行结果是: Car's call

可以看到使用这个方法之后,对象就能添加括号直接进行执行了。

instance.__class__属性

返回类实例所属的类。此属性可读写。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Car:
    def __init__(self):
        print('car')

class Bike:
    def __init__(self):
        print('bike')

c1 = Car()
class_c1 = c1.__class__  #获取实例c1所属的类
print(class_c1)

b1 = Bike()
class_b1 = b1.__class__  #获取实例b1所属的类
print(class_b1)

c1.__class__=Bike        #修改实例c1所属的类为Bike
class_c1 = c1.__class__  #获取实例c1所属的类
print(class_c1)

执行以上程序会输出如下结果:

1
2
3
4
5
car
<class '__main__.Car'>
bike
<class '__main__.Bike'>
<class '__main__.Bike'>

class.__subclasses__()

每个类都保留一个对其直接子类的弱引用列表。此方法返回所有仍处于活动状态的引用的列表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class A:
    pass

class B(A):
    pass

class C(B):
    pass

print(A.__subclasses__())
print(B.__subclasses__())
print(C.__subclasses__())

执行以上程序会输出如下结果:

1
2
3
[<class '__main__.B'>,<class '__main__.C'>]
[<class '__main__.C'>]
[]

操作对象属性的内置函数

.getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态。

getattr(object, name[, default])

返回对象的属性的值。name必须是字符串例如,getattr(x,’foobar’)相当于x.foobar。如果命名属性不存在,则返回default(如果提供),否则将引发attributeError。

hasattr(object, name)

如果字符串是对象某个属性的名称,则结果True;否则为False。

setattr(object, name, value)

设置对象的属性。setattr(x, ‘foobar’, 123) 相当于 x.foobar = 123.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class MyObject:
    def __init__(self):
        self.x = 9

    def power(self):
        return self.x * self.x

obj = MyObject()
print(hasattr(obj, 'x')) # 有属性'x'吗?True
print(hasattr(obj, 'y')) # 有属性'y'吗?False

setattr(obj, 'y', 19)    # 设置一个属性'y'
print(hasattr(obj, 'y')) # 有属性'y'吗?True
print(getattr(obj, 'y')) # 获取属性'y'  19
print(obj.y)             # 获取属性'y'   19

#可以传入一个default参数,如果属性不存在,就返回默认值:
print(getattr(obj, 'z', 404)) # 获取属性'z',如果不存在,返回默认值404

#也可以获得对象的方法:
print(hasattr(obj, 'power')) # 有属性'power'吗?True
print(getattr(obj, 'power')) # 获取属性'power'
print(type(getattr(obj, 'power')))  # 属性'power'的类型

fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
print(fn)  # fn指向obj.power

fn()       # 调用fn()与调用obj.power()是一样的

执行以上程序会输出如下结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
True
False
True
19
19
404
True
<bound method MyObject.power of <__main__.MyObject object at 0x7f13764b99b0>>
<class 'method'>
<bound method MyObject.power of <__main__.MyObject object at 0x7f13764b99b0>>

转载请注明本网址。