1、组合,将几个横向关系的组合在一起。所谓的组合就是将类的实例化放到新类里面,那么就将旧类组合进去了。

class Turtle:
def __init__(self, x): # 注意 init 前面必须双下划线
self.num = x class Fish:
def __init__(self, x):
self.num = x class Pool:
def __init__(self, x, y):
self.turtle = Turtle(x) # Pool类中实例化Turtle对象
self.fish = Fish(y) def print_num(self):
print('水池中共有乌龟 %d 只,小鱼 %d 条!'%(self.turtle.num,self.fish.num))

  调用结果:

pool = Pool(2, 7)
>>> pool.print_num()
水池中共有乌龟 2 只,小鱼 7 条!

  **:在新类中实例化旧类,如:self.turtle = Turtle(x) ,个人理解为将 Turtle 对象传递给 self.turtle 对象(属性),然后self.turtle 对象就具有Turtle 对象的属性了(体现在实例化 Pool 对象后,可以调用self.turtle.num,num 在 Pool 类中是没有定义的)。

  2、Mixin 简介

Mixin 编程是一种开发模式,是一种将多个类中的功能单元的进行组合的利用的方式,这听起来就像是有类的继承机制就可以实现,然而这与传统的类继承有所不同。通常 Mixin 并不作为任何类的基类,也不关心与什么类一起使用,而是在运行时动态的同其他零散的类一起组合使用。

特点

使用 Mixin 机制有如下好处:

  • 可以在不修改任何源代码的情况下,对已有类进行扩展;
  • 可以保证组件的划分;
  • 可以根据需要,使用已有的功能进行组合,来实现“新”类;
  • 很好的避免了类继承的局限性,因为新的业务需要可能就需要创建新的子类。

多继承

Python支持多继承,即一个类可以继承多个子类。可以利用该特性,可以方便的实现mixin继承。如下代码,类A,B分别表示不同的功能单元,C为A,B功能的组合,这样类C就拥有了类A, B的功能。

class A:
def get_a(self):
print 'a'
class B:
def get_b(self):
print 'b'
class C(A, B):
pass
c = C()
c.get_a()
c.get_b()

__bases__

多继承的实现就会创建新类,有时,我们在运行时,希望给类A添加类B的功能时,也可以利用python的元编程特性,__bases__属性便在运行时轻松给类A添加类B的特性,如下代码:

A.__bases__ += (B,)
a.get_b()

其实__bases__也是继承的机制,因为__bases__属性存储了类的基类。因此多继承的方法也可以这样实现:

class C:
pass
C.__bases__ += (A, B, )

插件方式

以上两种方式,都是基于多继承和python的元编程特性,然而在业务需求变化时,就需要新的功能组合,那么就需要重新修改A的基类,这回带来同步的问题,因为我们改的是类的特性,而不是对象的。因此以上修改会对所有引用该类的模块都收到影响,这是相当危险的。通常我们希望修改对象的行为,而不是修改类的。同样的我们可以利用__dict__来扩展对象的方法。

class PlugIn(object):
def __init__(self):
self._exported_methods = [] def plugin(self, owner):
for f in self._exported_methods:
owner.__dict__[f.__name__] = f
def plugout(self, owner):
for f in self._exported_methods:
del owner.__dict__[f.__name__]
class AFeature(PlugIn):
def __init__(self):
super(AFeature, self).__init__()
self._exported_methods.append(self.get_a_value)
def get_a_value(self):
print 'a feature.'
class BFeature(PlugIn):
def __init__(self):
super(BFeature, self).__init__()
self._exported_methods.append(self.get_b_value)
def get_b_value(self):
print 'b feature.'
class Combine:pass
c = Combine()
AFeature().plugin(c)
BFeature().plugin(c)
c.get_a_value()
c.get_b_value()

  

  3、类、类对象、实例对象

 class C:
count = 0 >>> a = C()
>>> b = C()
>>> c = C()
>>>a.count
0
>>> c.count += 10
>>> a.count
0
>>> b.count
0
>>> C.count += 100
>>> a.count
100
>>> b.count
100
>>> c.count
10

                              

  1)python中无处不对象。类中定义的属性时静态属性,类属性和类对象是绑定的,不依赖于实例对象。

  2)实例化对象后,进行实例对象属性的修改不会影响类对象的属性,所以 c.count += 10不会影响 C.count 的值。

  3)修改类对象属性属性之后,实例化对象的属性也会跟着改变,注意,经过实例对象修改过的属性不随着类属性的改变而改变(见上边染色部分代码),原因:个人理解为此处类似变量间的复制,实例对象是一个标签,和类对象指向同一个类属性地址,所以:a)类属性改变,实例对象属性跟着改变;b)单独修改实例对象属性是从新开辟堆栈,覆盖了该实例对象原本的类属性,所以这个修改不影响类属性,修改类属性也不影响经过修改的实例对象属性。

  4、如果属性名称和方法名称一样,属性名称会覆盖方法名称。如下:给实例对象 c 定义 x 属性之后,再调用 x() 方法会报错。

  4、绑定:Python 严格要求方法需要有实例才能够被调用,这种限制就是绑定概念。 个人理解:当实例对象调用方法时,会默认再方法里加一个 self 参数,如下面调用 bb.printBB()报错是因为 python默认的调用方式是 bb.printBB(bb),而 class BB 的printBB() 方法里面没有 self 参数,所以出现:TypeError :...but 1 was given 这个报错。

  下面这段代码验证上面的个人理解。

 class BB:
def printBB(self):
print('BB') >>> a = BB()
>>> a.printBB()
BB
>>> BB.printBB()
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
BB.printBB()
TypeError: printBB() missing 1 required positional argument: 'self'
>>> BB.printBB('b')
BB

  5、查看对象属性:对象.__dict__

   

组合,Mixin,类、类对象、实例对象的更多相关文章

  1. PHP 简单面向对象 验证码类(静态实例对象调用)

    没事写了一个简单的面向对象验证码类,可以直接使用(替换一下字体路径) <?php class authCode { private static $instance = null; #实例对象 ...

  2. Python高级语法-对象实例对象属性-类与实例,class方法静态方法等(4.6.1)

    @ 目录 1.说明 2.代码 关于作者 1.说明 python中属性:类属性,实例属性 方法:类方法,实例方法,静态方法 想修改类属性,只能是类方法,因为只有类方法把cls(类)传入数据里面 静态方法 ...

  3. Java 同一个类的不同实例对象竟然可以相互访问各自的private成员

    如题,在看String源码的某个函数时,发现了这个操作是被允许的,而且可以直接改变private字段(不是final按理是可以改变),这与之前的理解有点相背. 接下来试图整理下Google来的结论: ...

  4. Python高级语法-对象实例对象属性-Property总结(4.6.2)

    @ 目录 1.说明 2.代码 关于作者 1.说明 property属性,返回的是值 不是callable的,也就是不能使用方法来调用 只能传入self,不能传入其他 用处,能返回局部数据,比如当分页的 ...

  5. Python - 面向对象编程 - 什么是 Python 类、类对象、实例对象

    什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html Python 类 类定义语法 最简单的类定义看起来像这样 class ClassName: ...

  6. python中类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法

    类对象.类属性与实例对象.实例属性的区别 在Python中一切皆是对象,类是一个特殊的对象即类对象,描述类的属性称为类属性.类属性在内存中只有一份,在__init__外部定义. 通过类创建的对象称为实 ...

  7. js面向(基于)对象编程—类(原型对象)与对象

    JS分三个部分: 1. ECMAScript标准--基础语法 2. DOM  Document Object Model 文档对象模型 3. BOM  Browser Object Moldel 浏览 ...

  8. Python类的特点 (2) :类属性与实例属性的关系

    测试代码: #encoding:utf-8 class Parent(object): x=1 #x是Parent类的属性(字段) ls=[1,2] #ls是一个列表,也是Parent类的属性(字段) ...

  9. Python中的类属性、实例属性与类方法、静态方法

    1.什么是类对象,实例对象 类对象:类名 实例对象:类创建的对象 2.类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++.Java中类的静态成员变量有点 ...

  10. Python3 之 类属性与实例属性

    1.类属性与实例属性 类属性就相当与全局变量,实例对象共有的属性,实例对象的属性为实例对象自己私有. 类属性就是类对象(Tool)所拥有的属性,它被所有类对象的实例对象(实例方法)所共有,在内存中只存 ...

随机推荐

  1. js 回文判断

    方法一: 1.toLowerCase()     //统一小写. 2.split(" ").reverse().join(" "); //字符串翻转. func ...

  2. expect免互交 常用编辑文本

    expect免互交 yum -y install expect cat ip_pass.txt #这里写上要执行的IP地址和root用户密码 cat ssh2.exp #编写要执行的操作 #!/usr ...

  3. pip安装库时报错,使用国内镜像加速

    pip install requests或pip --trusted-host pypi.python.org install requests报错: 原因:网上解释为网速太慢,或被防火墙 解决方法: ...

  4. 『高性能模型』HetConv: HeterogeneousKernel-BasedConvolutionsforDeepCNNs

    论文地址:HetConv 一.现有网络加速技术 1.卷积加速技术 作者对已有的新型卷积划分如下:标准卷积.Depthwise 卷积.Pointwise 卷积.群卷积(相关介绍见『高性能模型』深度可分离 ...

  5. C++标准模板库(STL)之Vector

    在C中,有很多东西需要自己实现.C++提供了标准模板库(Standard Template Libray,STL),其中封装了很多容器,不需要费力去实现它们的细节而直接调用函数来实现功能. 具体容器链 ...

  6. mysql实现随机获取几条数据的方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/xionglangs/article/details/50630758sql语句有几种写法 1:SEL ...

  7. 原生js手动轮播图

    手动轮播图,为轮播图中的一种,轮播图主要有无缝轮播,手动轮播,延迟轮播,切换轮播等等... 轮播图主要用于展现图片,新出商品,词条,又能美观网页.給网页中增加动态效果. 手动轮播,是小编认为最简单的一 ...

  8. 小白的python之路Linux部分10/28&29

    属主属组其他人对文件的rwx权限 1.userdel删东西不全,会有残留,

  9. 大米网赚项目介绍,官方唯一客服QQ:486594009

    大米平台项目来源   QQ:486594009 大米软件本质上是一个高质量网赚项目收集和发布平台,该平台的所有项目都是经过专业的测试团队实测有效的项目和教程,只要去做绝对可以赚钱.平台里面的项目类型包 ...

  10. Python用起来极度舒适的强大背后

    当你使用len(a)获取a的长度,使用obj[key]获取一个key的值时的畅快和舒适,在于Python庞大的设计思想(Pythonic). 而obj[key]背后其实是__getitem__方法,P ...