面向对象编程2



1. 类和对象

类,就是class定义的东西

对象分两种,

类名称: 类名称用驼峰,类方法用下划线方式

2. Python的作用域和命名空间

类变量,实例变量,私有变量(公开)

# 类变量可以直接被程序引用
class Var(object):
    class_var = 'class variable'
    def __init__(self, var):
        self.var = var

if __name__ == '__main__':
    ins = Var('instance')
    print ins.class_var

# 执行结果
# class variable


# 实例变量的引用,需要self.var这种形式
class Var(object):
    class_var = 'class variable'
    def __init__(self, var):
        self.var = var
    def print_var(self):
        print self.var                  # print var会报错         
        print self.class_var

if __name__ == '__main__':
    ins = Var('instance')

    ins.print_var()

# 执行结果
# instance
# class variable

3. 继承

3.1 继承

>>> class A(object):
...     attr = 'A'
...
>>> class B(A):
...     pass
...
>>> b = B()
>>> b.attr
'A'

3.2 多重继承

>>> class A(object):
...     attr = 'A'
...
>>> class B(object):
...     attr = 'B'
...
>>> class C(A, B):
...     pass
...
>>> c = C()
>>> c.attr
'A'
# 继承优先级,从左到右,从上到下

3.3 class.mro()继承顺序

In [1]: class A(object):
   ...:     def say(self):
   ...:         print 'A'
   ...:

In [2]: class B(object):
   ...:     def say(self):
   ...:         print 'B'
   ...:

In [3]: class C(A, B):
   ...:     pass
   ...:

In [4]: c = C()

In [5]: c.say()
A
# 如何查看say函数的执行顺序
In [9]: print C.mro()
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]

3.4 如何初始化父类的内容?如何调用父类的函数?

In [10]: class D(A):
   ....:     def say(self):
   ....:         super(D, self).say()
   ....:         print 'D'
   ....:

In [11]: d = D()

In [12]: d.say()
A
D

# 也可以不用super(),super()只能作用于新式类
In [13]: class D(A):
    def say(self):
        A.say(self)
        print 'D'
   ....:

In [14]: d = D()

In [15]: d.say()
A
D

说下Mixin这个东西: Mixin

4. 私有变量和类内引用

4.1 self这个东西

__var

4.2 类变量何时被初始化

实例方法 实例传入方法,只有生成实例才可以使用的方法

静态方法 无需传入实例本身,无需传入类,无需实例化即可使用的方法

类方法 类不需要实例化,便可调用,但需要传入类到方法中

5. 动态添加类属性

class A:
     pass

a = A()
a.name = 'huyang'

6. 类之间关系:

6.1 UML (统一建模语言)

具体定义 日常使用

6.2 如何表示

6.3 模型表示

你去做一个数据库模型来,怎么做?

6.4 常见得几种关系

7. 接口的概念(抽象类)

参考Java中的概念 在Python中实现

可参考:https://docs.python.org/2/library/abc.html 很少用

8. 实现Python中的几种数据类型

9 高级–迭代器和生成器

9.1 t = (i for i in range(10))

# tuple生成器
>>> t = (i for i in range(10))
>>> print t, '\n', type(t)
<generator object <genexpr> at 0x7fd6e63107d0>
<type 'generator'>
# 列表推导式
>>> t = [i for i in range(10)]
>>> print t, '\n', type(t)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<type 'list'>

9.2. yield expression

简单例子

# 把yield放进func内部,那这个func被调用的时候就会传回一个生成器
>>> def yield_expression(num):
...     for i in range(num):
...         yield i
...

# num_list现在是个生成器
>>> num_list = yield_expression(10)
>>> print num_list, '\n', type(num_list)
<generator object yield_expression at 0x7fd6e63107d0>
<type 'generator'>

# 生成器可以用迭代的方式取出内容
>>> for i in num_list:
...     print i
...
0
1
2
3
4
5
6
7
8
9

如果有两个yield呢(两个yield放进一个for循环中)

>>> def yield_expression(num):
...     for i in range(num):
...         yield i
...         yield 'yield 2'
...
>>> num_list = yield_exppression(10)
>>> for i in num_list:
...     print i
...
0
yield 2
1
yield 2
2
yield 2
3
yield 2
4
yield 2
5
yield 2
6
yield 2
7
yield 2
8
yield 2
9
yield 2

如果有多个yield,但在不同的for循环中呢

>>> def yield_exp():
...     for i in range(3):
...         yield i
...     yield '-----------split line------------'
...     for j in range(3, 6):
...         yield j
...
>>> num_list = yield_exp()
>>> for i in num_list:
...     print i
...
0
1
2
-----------split line------------
3
4
5

9.3 给对象添加’iter’/‘next’方法

官方解释:https://docs.python.org/3/reference/expressions.html#yieldexpr

生成器是特殊的迭代器,生成器符合具有迭代器协议

补充知识:https://docs.python.org/2/library/collections.html

10. 作业

  1. 使用面向对象的方式完成学生信息管理系统。
  2. 《Python基础教程》上的项目1:即时标记
  3. 时间充裕的话:熟悉coding.net,把代码传上去。

扩展

纯记录下

globals()[‘string’]用来取方法名,变量名,很牛逼。研究数据类型的自带方法