《python基础教程》 --读书笔记(6)

对象和类

对象

  • 多态
      多态意味着就算不知道变量所引起的对象类型是什么,还是能对它进行操作,而它也会根据对象类型的不同而表现出不同行为。
    1. 多态和方法
      程序接受到一个对象,完全不了解对象的内部实现方式。只需知道它的某个方法如何调用,返回什么类型的值即可
from random import choice
# 标准库 random中包涵choice函数,可以从序列中随机挑选出元素,给变量赋值
# 运行后你不必关心x是那种类型,只需知道x有个叫count的方法及它的调用方式和返回值类
x = choice(["hello world", [1, 2, 3, "e", 4, "e"]])
print(x.count("e"))
  1. 多态的多种方式
    任何不知道对象到底是什么类型,但又要对象做点什么的时候,都会用到多态。很多函数和运算符都是多态的
# 打印对象长度
def length_message(obj):
    print("The length of", repr(obj), "is", len(obj))
length_message([1,2,3])
length_message("test")
  • 封装
      封装是指向程序中的其他部分隐藏对象的具体实现细节的原则
  • 继承
      如果不想把一段代码重复输入好几遍,之前使用函数避免这种情况。现在考虑这样一种情况,如果有了一个类,而又想建立一个非常类似的,新的类可能只是添加几个方法,不想把旧类的代码复制一遍的话,就要考虑指定超类。

类和类型

所有的对象都属于某一个类,称为类的实例

  • 创建类
# 确定使用新式类
_metaclass_ = type
class Person:
    def setName(self, name):
        self.name = name
    def getName(self):
        return self.name
    def greet(self):
        print("Hello, I'm %s." % self.name)
foo = Person()
# 在调用foo的setName函数时,foo自动将自己作为第一个参数传入函数中,所以命名为self
foo.setName("liu")
# 可以在外部访问
print(foo.name)
foo.greet()
  • 特性、函数、方法
  1. self参数正是方法和函数的区别。绑定方法将他们的第一个参数绑定到所属的实例上
  2. 默认情况下,程序可以从外部访问一个对象的特性。为了让方法或者特性变为私有,只要在他的名字前面加上双下划线即可。
# 私有特性
class Secretive:
    def __inaccess(self):
        print("you can't see me...")
    def accessble(self):
        print("The secret message is:")
        self.__inaccess()
s = Secretive()
# s.__insccess()
s.accessble()
  • 类的命名空间
    所有位于class语句中的代码都在特殊的命名空间中执行-类命名空间。这个命名空间可由类内所有成员访问。
# 类的命名空间
class MemberCounter:
    members = 0
    def init(self):
        MemberCounter.members += 1

m1 = MemberCounter()
m1.init()
print(MemberCounter.members)  # 1
m2 = MemberCounter()
m2.init()
print(MemberCounter.members)  # 2

# 类作用域的变量也可以被所有实例访问
print(m1.members)  # 2
print(m2.members)  # 2

# 重新绑定members
# 新members值被写到了m1的特性中,屏蔽了类范围内的变量
m1.members = "test"
print(m1.members)  # test
print(m2.members)  # 2
  • 指定超类
    子类可以扩展超类的定义,将其他类名写在class语句后的圆括号内可以指定超类。
# 指定超类
class Filter:
    def init(self):
        self.blocked = []
    def filter(self,sequence):
        return [x for x in sequence if x not in self.blocked]
# SPAMFilter 是 Filter的子类
class SPAMFilter(Filter):
    # 重写 超类中init方法
    def init(self):
        self.blocked = ["SPAM"]
# Filter 是个用于过滤序列的通用类,事实上它不能过滤任何东西
# Filter 可作为其他类的基类,比如SPAMFilter类,可以将序列中的"SPAM"过滤出去
s = SPAMFilter()
s.init()
# ['1', '2', '3', '4']
print(s.filter(["1", "SPAM", "2", "SPAM", "3", "4"]))
  • 继承检查
    如果想要查看一个类是否是另一个的子类,可以使用内建的issubclass函数
# 检查继承 issubclass函数
print(issubclass(SPAMFilter, Filter)) #  True
print(issubclass(Filter, SPAMFilter)) #  False	·
# 想要知道已知类的基类
print(SPAMFilter.__bases__) #  (<class '__main__.Filter'>,)
print(Filter.__base__) #  <class 'object'>		 
# 检查实例 isinstance
print(isinstance(s, Filter)) #  True
print(isinstance(s, SPAMFilter)) #  True
print(isinstance(s, str)) #  False	
# 想要知道对象属于哪一个类
print(s.__class__) # <class '__main__.SPAMFilter'>
  • 多个超类
# 多个超类
class Calcuator:
    def calculate(self, expression):
        self.value = eval(expression)
class Talker:
    def talk(self):
        print("value is ", self.value)
# 从Calcuator类那里继承calculate方法,从Talker那里继承talk方法
class TalkingCalcuator(Calcuator, Talker):
    pass
tc = TalkingCalcuator()
tc.calculate("1+2+4")
tc.talk() # value is  7
  • 接口和内省
    接口的概念与多态有关,在处理多态对象时,只关心他的接口(或者称"协议")即可,也就是公开的方法和特性。

关于面对对象设计的思考

  • 将属于一类的对象放在一起。如果一个函数操纵一个全局变量,那么两者最好都在类内作为特性和方法出现
  • 不要让对象过于亲密,方法应该只关心自己实例的特性,让其他实例管理自己的状态
  • 要小心继承,尤其是多重继承。继承很有用,但也会在某些情况下让事情变得过于复杂,难以调试
  • 简单就好,让你的方法小巧,大多数方法因该都在30秒内被读完
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值