【Python-8】面向对象

面向对象的关键概念:多态、封装、方法、属性、超类和继承。

多态

repr 是多态的集大成者之一,可用于任何对象

def length_message(x):
    print("The length of", repr(x), "is", len(x))
​
length_message('Fnord')
length_message([1, 2, 3])
length_message({"1":"shuqiang", "2":"xuxing"})
The length of 'Fnord' is 5
The length of [1, 2, 3] is 3
The length of {'1': 'shuqiang', '2': 'xuxing'} is 2

封装

封装不同于多态。多态让你无需知道对象所属的类(对象的类型)就能调用其方法,而封装让你无需知道对象的构造就能使用它。 封装就是将类所有操作封装成类的方法。修改累的成员的时候,不直接修改,而是调用类的方法修改。

class AddBook(object):
    def __init__(self, name, phone):
        self.name = name
        self.phone = phone
​
    def get_phone(self):
        return self.phone
    
my_object = AddBook("xuxing", "8766185") # 对象就是这样创建的
print(my_object.get_phone())
​
8766185

继承

举个例子,要做一个数学计算软件,有三个类:画直线的类A,画弧线的类B,这个时后你需一个话函数图像的类,那么有了类A/B,就可以直接将A/B的方法继承放在C中,作为新的类。避免了代码重复。

class Filter:
    def init(self):
        self.blocked = []
    def filter(self, sequence):
        return [x for x in sequence if x not in self.blocked]
​
class SPAMFilter(Filter): # SPAMFilter是Filter的子类
    def init(self): # 重写超类Filter的方法init
        self.blocked = ['SPAM']
​
# 要确定一个类是否是另一个类的子类,可使用内置方法 issubclass 
# 子类继承父类,父类的功能少,子类功能更多。
​
# --1:判断SPAMFilter 是否是 Filter的子类
ret = issubclass(SPAMFilter, Filter)
print(ret)
​
s = SPAMFilter()
s.init()
ret = s.filter(['SPAM', 'SPAM', 'SPAM', 'SPAM', 'eggs', 'pig', 'SPAM'])
print(ret)
​
# --2: 如果你有一个类,并想知道它的基类,可访问其特殊属性 __bases__ 
ret = SPAMFilter.__bases__
print(ret)
​
# --3:同样,要确定对象是否是特定类的实例,可使用 isinstance 
s = SPAMFilter()
ret = isinstance(s, SPAMFilter)
print(ret)
1
2
True
['eggs', 'pig']
(<class '__main__.Filter'>,)
True

对面向对象设计的思考

  • 将相关的东西放在一起。如果一个函数操作一个全局变量,最好将它们作为一个类的属性和方法。
  • 不要让对象之间过于亲密。方法应只关心其所属实例的属性,对于其他实例的状态,让它们自己去管理就好了。
  • 慎用继承,尤其是多重继承。继承有时很有用,但在有些情况下可能带来不必要的复杂性。要正确地使用多重继承很难,要排除其中的bug更难。
  • 保持简单。让方法短小紧凑。一般而言,应确保大多数方法都能在30秒内读完并理解。对于其余的方法,尽可能将其篇幅控制在一页或一屏内。

确定需要哪些类以及这些类应包含哪些方法时,尝试像下面这样做。
(1) 将有关问题的描述(程序需要做什么)记录下来,并给所有的名词、动词和形容词加上标记。
(2) 在名词中找出可能的类。
(3) 在动词中找出可能的方法。
(4) 在形容词中找出可能的属性。
(5) 将找出的方法和属性分配给各个类。
有了面向对象模型的草图后,还需考虑类和对象之间的关系(如继承或协作)以及它们的职责。为进一步改进模型,可像下面这样做。
(1) 记录(或设想)一系列用例,即使用程序的场景,并尽力确保这些用例涵盖了所有的功能。
(2) 透彻而仔细地考虑每个场景,确保模型包含了所需的一切。如果有遗漏,就加上;如果
有不太对的地方,就修改。不断地重复这个过程,直到对模型满意为止。

重要函数总结

  • callable(object)
    判断对象是否是可调用的(如是否是函数或方法)
  • getattr(object,name[,default])
    获取属性的值,还可提供默认值
  • hasattr(object, name)
    确定对象是否有指定的属性
  • isinstance(object, class)
    确定对象是否是指定类的实例
  • issubclass(A, B)
    确定 A 是否是 B 的子类
  • random.choice(sequence)
    从一个非空序列中随机地选择一个元素
  • setattr(object, name, value)
    将对象的指定属性设置为指定的值
  • type(object)
    返回对象的类型
发布了134 篇原创文章 · 获赞 119 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/jobbofhe/article/details/90033283