一、类和对象
面向对象是一种编程的思想。面向对象的核心概念就是抽象、继承、多态。
类由属性和方法组成,通俗点理解就是,属性就是类内部包含的数据,而方法则是在类内部定义的函数。
Python的类分为经典类和新式类,区别在于新式类默认继承object类。而object类是Python的内置类,其中具有很多方法,在3.x版本中左右的类均为object的子类。建议尽可能地使用新式类。
1、创建类的例子:
class class_name:
data = []
def fun1(self):
pass
...
2、实例化
实例化就是创建一个类的对象,可以把类想象成模板,而类的对象就是在该模板下创造的对象,其具有模板的属性和方法。
class PrintSelf:
def __init__(self, data):
self.data = data
def self_print(self):
print(self.data)
ob1 = PrintSelf('hahha')
ob1.self_print()
3、类的继承
继承又叫做泛化,是使类获得另一个类的所有属性和方法的能力,被继承的类称为父类或者基类,继承的类称为子类或派生类。子类可以有一个或者多个父类,子类自动继承所有父类的属性和方法。如果只继承一个父类,那就叫做单一继承。
class A:
def print_fun(self):
print('print class_A')
class B:
def print_B(self):
print('print class_B')
class C(A, B):
def print_fn(self):
# 调用父类方法
print(A.print_fun(self), B.print_B(self))
if __name__ == '__main__':
a = A()
b = B()
c = C()
a.print_fun()
b.print_B()
c.print_fn()
二、元类和新式类
1、元类
元类是Python语言中的高级主题,元类动态的生成类的能力能够更方便的解决以下情况:
类在设计时并不是所有部分都要知道细节;
在某些情况下,类比实例更重要
但是并不是必须的一种功能。在Python中,每一个类都是经过元类实例化而来的,在大多数情况下,这一过程由编译器来完成。通过设置metaclass属性,可以自定类的元类属性。如果将metaclass设置为全局变量,那么在该名字空间下的所有类的元类都将是metaclass所指向的元类。
class ChattyType(type):
"""
定义了元类
"""
def __new__(cls, name, bases, dct):
print("Allocating memory for class", name)
return type.__new__(cls, name, bases, dct)
def __init__(cls, name, bases, dct):
super(ChattyType, cls).__init__(name, bases, dct)
print("Init class", name)
class example(metaclass=ChattyType):
"""
元类实例化该类过程
"""
def __init__(self):
print("this is init!")
if __name__ == '__main__':
a = example()
2、新型类
在3.x的版本中,其类均为新型类,新型类继承自object类或其子类。实际上所有的内建类型都是从object·类继承而来·。新的对象模型提供了两种类的新方法:
静态方法可以直接被类或者类的实例对象调用,也就是说静态函数的第一个参数不需要被指定为self。
class Test:
"""
类的内部创建静态函数
"""
@staticmethod
# 该关键字修饰静态方法
def test_print():
print('this is static_method')
if __name__ == '__main__':
t = Test()
t.test_print()
类的常规方法不需要修饰。
3、新型类的特定方法
__new__和__init__方法:
新型类包含new方法,当实例化一个类的时候,实际上是使用new方法创建该类的一个实例对象,该方法的返回值x就是该类的实例对象。
class TestOne:
def __new__(cls):
print('this is new method')
return object.__new__(cls)
def __init__(self):
print('this is init method')
if __name__ == '__main__':
t = TestOne()
可以看到,new的作用是接受一个类作为参数,返回该类的实例。而init用来初始化该实例。也就是说:new用来分配内存生成类实例,init负责对实例对象进行初始化。
4、类的super()方法:
新型类提供了一个特殊的方法super(),super(aclass, obj)返回obj的一个特殊的超对象。当我们调用该超对象的属性或者方法时,就保证了每个父类的实现均被调用且仅调用一次。例入下面的代码:
class _fasterRCNN(nn.Module):
""" faster RCNN """
def __init__(self, classes, class_agnostic):
super(_fasterRCNN, self).__init__()
self.classes = classes
self.n_classes = len(classes)
self.class_agnostic = class_agnostic
# loss
self.RCNN_loss_cls = 0
self.RCNN_loss_bbox = 0
# define rpn
self.RCNN_rpn = _RPN(self.dout_base_model)
self.RCNN_proposal_target = _ProposalTargetLayer(self.n_classes)
self.RCNN_roi_pool = _RoIPooling(cfg.POOLING_SIZE, cfg.POOLING_SIZE, 1.0/16.0)
self.RCNN_roi_align = RoIAlignAvg(cfg.POOLING_SIZE, cfg.POOLING_SIZE, 1.0/16.0)
self.grid_size = cfg.POOLING_SIZE * 2 if cfg.CROP_RESIZE_WITH_MAX_POOL else cfg.POOLING_SIZE
self.RCNN_roi_crop = _RoICrop()