在前面已经介绍过__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)
|
执行以上程序会输出如下结果:
因为不是按照系统的方式创建对象,所以就不会调用__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)
|
执行以上程序会输出如下结果:
析构函数__del__()
__init__()在对象被创建的时候进行调用,成为初始化函数。而对象被销毁的时候就会调用__del__()函数,成为析构函数。
1
2
3
4
5
6
|
class Car:
def __init__(self):
print('我被创建了')
def __del__(self):
print('我要被销毁了')
c1=Car()
|
执行以上程序会输出如下结果:
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>>
|
转载请注明本网址。