python 对象

摘要

经过前面的学习我们已经掌握了内建对象类型(函数 字符串 列表 元祖 字典)

以及内建函数和标准库的用法,还有定义函数的方法 。


next We are will Study 创建自己的对象(自定义对象)

类型或者叫做类的对象》》这是Python非常核心的概念。As we all known

Python 被称为面向对象的语言(SmallTalk 、C++、 Java、)

接下来 我们会介绍如何创建对象,以及多态、封装、方法、特性、超类以及继承的概念。

新知识很多,Now We Are Starting .

=========================================================================

对象最重要的优点:

  • 多态:

            意味着可以对不同类的对象使用相同的操作。
    
  • 封装

            对外部世界隐藏对象的工作细节
    
  • 继承

    以通用的类为基础建立专门的类的对象


术语:多态来自希腊语,意思是“有多种形式”。
多态意味着就算不知道变量所引用的对象类型是什么,还是能对它进行操作,而它也会根据对象(或类)类型的不同而表现出不同的行为。
- 让对象自己进行操作
多态和方法
绑定到对象特性上面的函数称为方法(method),

封装

可以不用关心对象是如何构建的而直接进行使用。

继承

它是另外一个懒惰(褒义)的行为。程序员不想把同一段代码输入好几次,

类和类型

类为种类或类型的同义词。从很多方面来说,这就是类—一种对象。
所有的对象都属于一个类,称为类的实列(instance)。
鸟类(所有鸟的集合)具有很多子类(百灵鸟类)子类(subclass)
故:鸟类为百灵鸟类的超类(Superclass)


在面向对象程序设计中,子类的关系是隐式的,因为一个类的定义取决于它所支持的方法。

类的所有(instance)都会包含这些方法,所以所有子类的所有实列都有这些方法。

定义子类:

只是个定义更多(也有可能是重载已经存在的方法的过程)。

Eg:

Bird(可能支持fly方法),而企鹅类(Penguin)可能会增加个Eatfish的方法。

当创建penguin类时。可能会想重写(override)超类的fly方法。对于penguin的实列来说,

这个方法要么什么也不做,要么就产生异常(因为企鹅不会飞)。

区别

在旧版本的python中,内奸的对象是基于类型的,自定义的对象则是基于类的。可以创建类但是不可以创建类型。

最近版本的Python中,游乐一定变化,基本类型和类之间的界限开始模糊了。可以创建内建类型的子类,而这些类型的行为更类似于类。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

创建自己的类

先来看一个简单的类!!

    _metaclass_=type#确定使用新式类
    class Person:
        def setName(self,name):
            self.name=name

            def getName(self):
                return self.name

            def greet(self):
                print ("Hello,world!I'm %s." % self.name)

新式类:需要在模块或者脚本开始的地方放置赋值语句:

_metaclass_=typepyth3.0之后已不存在旧式类。

接下来让我们创建一些实列看看:

     foo=Person()
                    bar=Person()
                    foo.setName('ChengKaoAo')
                    bar.setName('MeiXuanZheng')
    ···
>特性、函数和方法
self参数事实上正是方法和函数的区别:
方法(更专业一点可以成为绑定方法)将它们的第一个参数绑定到所属的实列上,因此你无需显示提供参数。当然你也可以将特性绑定到一个普通函数上,这样就不会有特殊的self参数了。

再论私有化

默认情况下,程序可以从外部访问一个对象特性。

为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上双下划线即可:

    class Secretive:  
        def __inaccessible(self):  
            print "Bet you can't see me..."  
        def accessible(self):  
            print "The secret message is:"  
            self.__inaccessible()  
    s = Secretive()  
    s.accessible()  

类的命名和空间

所有位于class语句中的代码都在特殊命名空间执行——类命名空间。这个命名空间可由类内所有成员访问。并不是所有python程序员都知道类的定义其实就是执行代码块

这一点非常有用,比如在类的定义区并不只限定只能使用def语句:

    class C:
        print ('Class C being defined:')
        #继续>>>
    class MemberCounter:
        members=0
        def init(self):
            MemberCounter.menbers+=1

指定超类

子类可以扩展超类的定义。将其他类名写在class语句后的圆括号内可以指定超类:

  #_*_ coding:utf8 _*_  
    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']  

    f = Filter()  
    f.init()  
    print f.filter([1,2,3])  

    s = SPAMFilter()  
    s.init()  
    print s.filter(['SPAM','SPAM','SPAM','SPAM','eggs','bacon','SPAM']) 

Run Result:

这里用提供新定义的方式重写了Filter的init定义。

  • filter方法的定义是从Filter类中拿过来的,所以不用重写它的定义。

  • 第二个要点就是揭示了继承的用处:我们可以写一大堆不同的过滤类,全都从Filter继承,每一个我都可以使用已经实现的filter方法。

检查继承

如果想要查看一个类是否是否是另一个的子类,可以使用内建的issubclass函数:

   # _*_ coding:utf8 _*_
    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']


    print issubclass(SPAMFilter, Filter)
    print issubclass(Filter, SPAMFilter) 

The Run Result

多个超类

一个类地基类可能会多于一个,EG:

子类(TalkingCalculator)自己不做任何事,它从自己的超类继承所有的行为。

它从Calculator类哪里继承Calculate方法,从Talke类哪里继承talk方法,这样它就成了会说话的

计算器(talking calculator)

这种行为叫做多重继承。除非非常熟悉,否则应尽量避免使用,因为有时会出现不可预见的麻烦,

    # _*_ coding:utf8 _*_
    class Calculator:
        def calculate(self,expression):
            self.value = eval(expression)
            class Talker:
                def talk(self):
                    print 'Hi,my value is',self.value

                    class TalkingCalculator(Calculator, Talker):
                        pass

                    tc = TalkingCalculator()
                    tc.calculate('1+2*3+1')
                    tc.talk()

当有2个相同名字的不同方法时,需要注意超类的顺序(在Class语句中),先继承的类中的方法会重写后继承的类中的方法,

接口和内省

“接口”的概念与多态有关。

  • 在处理多态对象时,只要关心他的接口(或称“协议”)即可,也就是公开的方法和特征。

  • 在Python中,不用显式地指定对象必须包含哪些方法才能作为参数接收。
    一般来说只需要让对象符合当前的接口(就是实现当前的方法),但是还可以更灵活一些。
    除了调用方法然后期待一切顺利之外,还可检查所需方法是否已经存在。


关于面向对象的思考

要点:

  • 将属于一类的对象放在一起。如果一个函数操纵一个全局变量,那么两者最好都在类内作为特征和方法出现。

  • 不要让对象过于亲密。方法应该只关心自己实例的特征。让其他实例管理自己的状态。

  • 要小心继承,尤其是多重继承。继承机制有时很有用,但也会在某些情况下让事情变得过于复杂。多继承难以正确使用,更难以调试。
  • 简单就好。让你的方法小巧。一般来说,多数方法都应该在30秒内被读完(以及理解),尽量将代码行数控制在一页或者一屏之内。

当考虑需要什么类以及类要有什么方法时,应该尝试下面的方法。

(1)写下问题的描述(程序要做什么),把所有名词、动词、形容词加下划线

(2)对于所有名词,用作可能的类。

(3)对于所有动词,用作可能的方法。

(4)对于所有形容词,用作可能的特性。

(5)把所有方法特性分配到类。

现在已经有了面向对象模型的草图了,还可以考虑类和对象之间的关系(比如继承或协作)

以及它们的作用,可以用以下步骤精炼模型。

(1)写下(想象)一系列使用实列,也就是程序应用时的场景,试着包括所有的功能。

(2)一步步考虑每个使用实列,保证每个模型包括所有需要的东西,如果有遗漏的话就添加进来,

如果某处不太正确则改正。继续,到满意为止。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值