• 【九】面向对象


    一:使用class定义类

    假设你要定义一下对象用于记录联系人,每个对象对应一个人,首先需要定义person类作为生产对象的模具。

    首先创建一个没有任何内容的空类:

    In [301]: class person():
         ...:     pass

    二:对类进行初始化

    init()是python中一个特殊的函数名,用户根据类的定义创建实例对象,self参数指向了这个正在被创建对象本身

    #定义一个person类
    #给person类创建一个初始化函数
    In [302]: class person():
         ...:     def __init__(self,name):
         ...:         self.name=name
         ...:         

    用person类创建一个对象,为name特性传递一个字符串参数:

    #python执行:person.__init__(huahua,"cmf"),self代表实例化的对象,这个例子指的是huahua
    In [304]: huahua=person("cmf")
    In [305]: huahua.name
    Out[305]: 'cmf'

    上述代码做了如下工作:

    1. 查看person类的定义
    2. 在内存中实例化一个新的对象
    3. 调用对象的init方法,将这个新创建的对象作为self传入,并将并一个参数cmf作为name传入
    4. 将name的值存入对象
    5. 返回这个新的对象
    6. 将huahua与这个对象关联

    三:继承

    利用类的继承,从已有类中衍生出新的类,添加和修改部分功能。使用继承得到的新类会自动获取旧类中的很多方法,从而不需要复制

    #创建一个person类
    In [306]: class person():
         ...:     pass
    #创建一个testperson类,继承person
         ...: class testperson(person):
         ...:     pass 

    接着,为每个类创建一个实例对象:

    In [307]: ren=person()
    In [308]: test1=testperson()

    子类是父类的一种特殊情况,它属于父类

    #创建父类
    In [310]: class person():
         ...:     def exclain(self):
         ...:         print("i am a person")
         ...:         
    #创建子类,并继承父类
    In [311]: class testperson(person):
         ...:     pass
         ...: 
    #实例化
    In [312]: ren=person()
    In [313]: test=testperson()
    #调用父类的方法
    In [314]: ren.exclain()
    i am a person
    #调用父类的方法
    In [315]: test.exclain()
    i am a person

    四:覆盖方法

    新创建的子类会自动继承父类的所有信息,接下来我们来看看子类如何替代(覆盖)父类的方法

    In [316]: class person():
         ...:     def exclain(self):
         ...:         print("i am a person")
         ...:  
    #创建一个新的同名方法,覆盖父类方法       
    In [317]: class testperson(person):
         ...:     def exclain(self):
         ...:         print("i am a testperson")
         ...:         
         ...: 
    In [318]: ren=person()
    In [319]: test=testperson()
    In [320]: ren.exclain()
    i am a person
    In [321]: test.exclain()
    i am a testperson

    为子类添加新方法

    In [325]: class person():
         ...:     def __init__(self,name):
         ...:         self.name=name
         ...:         
         ...:         
    In [326]: class testperson(person):
         ...:     def __init__(self,name,email):
         ...:         super().__init__(name) #super:继承父类的name方法
         ...:         self.email=email
         ...:         
    In [327]: test=testperson("test","test@qq.com")
    In [328]: test.name
    Out[328]: 'test'
    In [329]: test.email
    Out[329]: 'test@qq.com'
    In [330]: ren=person("ren")
    In [331]: ren.name
    Out[331]: 'ren'
    #父类不能访问子类特有的方法
    In [332]: ren.email
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-332-0d7ad82f0acc> in <module>()
    ----> 1 ren.email
    
    AttributeError: 'person' object has no attribute 'email'

    五:property属性

    property() 函数的作用是在新式类中返回属性值。

    In [375]: class duck():
         ...:     def __init__(self,input_name):
         ...:         self.hidden_name=input_name
    #定义get和set方法
         ...:     def get_name(self):
         ...:         print("inside the getter")
         ...:         return self.hidden_name
         ...:     def set_name(self,input_name):
         ...:         print("inside the setter")
         ...:         self.hidden_name=input_name
         ...:     name=property(get_name,set_name)
         ...: 
    #方式1    
    In [376]: fowl=duck("caicai")
    In [377]: fowl.name
    inside the getter
    Out[377]: 'caicai'
    In [378]: fowl.get_name()
    inside the getter
    Out[378]: 'caicai'
    #方式二
    In [379]: fowl.name="cmf"
    inside the setter
    In [380]: fowl.name
    inside the getter
    Out[380]: 'cmf'
    #方式三
    In [382]: fowl.set_name("caiminfang")
    inside the setter
    In [383]: fowl.name
    inside the getter
    Out[383]: 'caiminfang'

     实例

    In [2]: class Duck():
       ...:     def __init__(self,input_name):
       ...:         self.hidden_name=input_name
       ...:     @property
       ...:     def name(self):
       ...:         print("insede the getter")
       ...:         return self.hidden_name
       ...:     @name.setter
       ...:     def name(self,input_name):
       ...:         print("inside the setter")
       ...:         self.hidden_name=input_name
       ...:         
    In [3]: ff=Duck("huahua")
    In [4]: ff.name
    insede the getter
    Out[4]: 'huahua'
    In [5]: ff.name="cmf"
    inside the setter
    In [6]: ff.name
    insede the getter
    Out[6]: 'cmf'

    property底层代码

    In [7]: property?
    Init signature: property(self, /, *args, **kwargs)
    Docstring:     
    property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
    
    fget is a function to be used for getting an attribute value, and likewise
    fset is a function for setting, and fdel a function for del'ing, an
    attribute.  Typical use is to define a managed attribute x:
    
    class C(object):
        def getx(self): return self._x
        def setx(self, value): self._x = value
        def delx(self): del self._x
        x = property(getx, setx, delx, "I'm the 'x' property.")
    
    Decorators make defining new properties or modifying existing ones easy:
    
    class C(object):
        @property
        def x(self):
            "I am the 'x' property."
            return self._x
        @x.setter
        def x(self, value):
            self._x = value
        @x.deleter
        def x(self):
            del self._x
    Type:           type

    六:类方法

    也叫类型方法,用@classmethod做标记的方法.假设其有n个必传参数,如果是类调用,则需要传n-1个参数,第一个参数同样是内定的类型本身。如果是实例调用,则需要传n个参数。类方法要让类型能调用,当然也需要至少一个参数.

    类方法,第一个参数必须要默认传类,一般习惯用cls。

    In [24]: class a():
        ...:     count=0
        ...:     def __init__(self):
        ...:         a.count+=1
        ...:         print(a.count)
        ...:     def ex(self):
        ...:         print("i am a")
        ...:     @classmethod
        ...:     def kids(cls):
        ...:         print("a has",cls.count)
        ...:         
    
    In [25]: aa=a()
    1
    
    In [26]: bb=a()
    2
    
    In [27]: cc=a()
    3
    
    In [28]: a.kids()
    a has 3

    七:静态方法

    @staticmethod标记的方法。类和实例都可以调用。无内定的参数问题,方法有多少参数就必须传递多少参数。

    静态方法,参数没有要求。下面例子为空

    In [29]: class a():
        ...:     @staticmethod
        ...:     def name():
        ...:         print("name")
        ...:         
    
    In [30]: a.name()
    name

    八:魔术方法

    除了__init__()外,还有最常用的__str__(),他用于定义如何打印信息。print()方法,str()方法以及一些字符串格式化的相关方法都会用到__str__(),交互式解释器则用__repr__()方法输出变了。

    如果你的类既没有定义__str__()也没有定义___repr__(),python会输出类似下面的默认字符串:

    In [37]: class word():
        ...:     def __init__(self,text):
        ...:         self.text=text
        ...:     def equals(self,word2):
        ...:         return self.text.lower()==word2.text.lower()
        ...:     
    
    In [38]: first=word('ha')
    
    In [39]: second=word("qwe")
    
    In [40]: third=word('HA')
    
    In [41]: first.equals(third)
    Out[41]: True
    
    In [42]: first.equals(second)
    Out[42]: False
    
    In [43]: first==second
    Out[43]: False
    #由于该类中没有__str__(),__repr__()方法,所以出现了下面的字符串
    In [44]: first
    Out[44]: <__main__.word at 0x7f841efaaeb8>

    我们将__str__()和__repr__()方法都加到word类中,让输出的信息更变好看些

    In [45]: class word():
        ...:     def __init__(self,text):
        ...:         self.text=text
        ...:     def equals(self,word2):
        ...:         return self.text.lower()==word2.text.lower()
        ...:     def __str__(self):
        ...:         return self.text
        ...:     def __repr__(self):
        ...:         return 'word('+self.text+')'
        ...:     
    
    In [46]: first=word('ha')
    
    In [47]: first
    Out[47]: word(ha)
    
    In [48]: print(first)
    ha

    九组合(compositoon)和聚合(aggregation)

    In [62]: class hair():
        ...:     def __init__(self,color):
        ...:         self.color=color
        ...:         
    #定义头发的颜色
    In [63]: class mouth():
        ...:     def __init__(self,size):
        ...:         self.size=size
        ...:         
    #定义嘴巴的函数
    In [64]: class Person():
        ...:     def __init__(self,hair,mouth):
        ...:         self.hair=hair
        ...:         self.mouth=mouth
        ...:     def about(self):
    #print(Hair.color,Mouth.size)该处的Hair必须写hair的实例化对象
        ...:         print(Hair.color,Mouth.size)
        ...:         
    In [65]: Hair=hair("yellow")
    In [66]: Mouth=mouth("small")
    In [67]: person=Person(Hair,Mouth)
    In [68]: person.about()
    yellow small
  • 相关阅读:
    基于ASP.NET的comet简单实现
    常用的富文本框插件FreeTextBox、CuteEditor、CKEditor、FCKEditor、TinyMCE、KindEditor ;和CKEditor实例
    关于Application.Lock和Lock(obj)
    asp.net 母版页使用详解--转
    ASP.NET 全局变量和页面间传值方法
    黑帽大会2014:10个酷炫的黑客工具
    python之高性能网络编程并发框架eventlet实例
    eCos中的线程与同步
    Ubuntu12.04 下修改Apache端口号
    PHP 之mysql空字符串问题
  • 原文地址:https://www.cnblogs.com/8013-cmf/p/7102845.html
Copyright © 2020-2023  润新知