zoukankan      html  css  js  c++  java
  • python之封装与扩展性

    1.封装与扩展性

    封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用的代码;而外部使用者只知道一个接口(函数),只要接口(函数)名,参数不变,使用者的代码永远无需改变。这就提供了一个良好的合作基础——或者说,只要这个基础约定不变,则代码改变不足为虑。

    def __init__(self,width,length):
    
     
    
            self.width=width
    
            self.length=length
    
     
    
        def area(self):#对外提供了接口,隐藏了内部的实现细节,此时求的是面积
    
            return self.width*self.length
    
        
    
     
    
    #使用者
    
    r1=Room(30,20)
    
    print(r1)
    
    print(r1.area())#使用者调用接口area
    
     
    
    <__main__.Room object at 0x03720650>
    
    600
    
     
    

      

    #类的设计者,轻松的扩展了功能,而类的使用者完全不需要更改自己的代码

    class Room:
    
        def __init__(self,width,length,higt):
    
            self.width=width
    
            self.length=length
    
            self.higth=higt
    
        def area(self):
    
            return self.length*self.width*self.higth
    
        #对外提供的接口,隐藏内部实现,此时求的是体积,内部逻辑变了,只需要修改一行
    
        # 就可以实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了
    
     
    
    r2=Room(30,20,20)
    
    print(r2)
    
    print(r2.area())
    
     
    
    <__main__.Room object at 0x039B0750>
    
    12000
    

      

    2.静态封装

    Staticmethod 使用方法

    静态方法是一种普通函数,位于类定义的命名空间中,不会对任何实例类型进行操作,python为我们内置了函数staticmethod来把类中的函数定义成静态方法

    class Foo:
    
        @staticmethod#装饰器,实例在使用时丧失了自动传值的机制
    
        def spam(x,y,z):#把函数spam做成静态方法
    
            print(x,y,z)
    
     
    
    f1=Foo()
    
    f1.spam(1,2,3)#此时函数中有几个参数就需要传几个值
    
     
    
    1 2 3
    

      

    应用场景

    import time
    
    class Date:
    
        def __init__(self,year,month,day):
    
            self.year=year
    
            self.month=month
    
            self.day=day
    
        @staticmethod
    
        def now():#用Date.now()的形式去产生实例,该实例是当前的时间
    
            t=time.localtime()#获取结构式的时间格式
    
            return Date(t.tm_year,t.tm_mon,t.tm_mday)#新建实例并返回
    
        @staticmethod
    
        def tomorrow():#用Date.now()的形式去产生实例,该实例是明天的时间
    
            t=time.localtime(time.time()+86400)
    
            return Date(t.tm_year,t.tm_mon,t.tm_mon)
    
    a=Date(1987,11,22)#自己定义时间
    
    b=Date.now()#采用当前时间
    
    c=Date.tomorrow()#采用明天的时间
    
    print(a.year,a.month,a.day)
    
    print(b.year,b.month,b.day)
    
    print(c.year,c.month,c.day)
    
     
    
    1987 11 22
    
    2017 4 22
    
    2017 4 23
    

      

    @staticmethod相当于给类(类的功能:属性应用和实例化)添加了一个实例化的功能,之前只能是类()进行,现在扩展一个功能,直接加@staticmethod,对象可以调用。

    如果不使用@staticmethod,实例调用时就会产生绑定方法,必须传入self;

    但凡是定义在类的内部,并且没有被任何装饰器修饰过的方法,都是绑定方法:有自动传值功能。

    3.类方法

    @classmethod

    类方法是给类使用的,类在使用时会将类本身当做参数传给类方法的第一个参数,,python为我们内置了函数classmethod来把类中的函数定义成类方法

    class Foo:
    
        def bar(self):
    
            pass
    
        @classmethod
    
        def test(cls):#把一个方法绑定到类:类.绑定到类的方法()
    
            #会把类本身当做第一个参数自动传给绑定到类的方法(相当于self的概念)
    
            print(cls)
    
    print(Foo.bar)
    
    print(Foo.test)
    
     
    
    <function Foo.bar at 0x032D4078>
    
    <bound method Foo.test of <class '__main__.Foo'>>
    

      

    实现类本身当做第一个参数自动传给绑定到类的方法

    class Foo:
    
        def bar(self):
    
            pass
    
        @classmethod
    
        def test(cls):#把一个方法绑定到类:类.绑定到类的方法()
    
            #会把类本身当做第一个参数自动传给绑定到类的方法(相当于self的概念)
    
            print(cls)
    
    # print(Foo.bar)
    
    # print(Foo.test)
    
    Foo.test()
    
    <class '__main__.Foo'>
    

      

    class Foo:
    
        def bar(self):
    
            pass
    
        @classmethod
    
        def test(cls,k):#把一个方法绑定到类:类.绑定到类的方法()
    
            #会把类本身当做第一个参数自动传给绑定到类的方法(相当于self的概念)
    
            print(cls,k)#拿到一个类的内存地址,就可以实例化或者引用类的属性了
    
    # print(Foo.bar)
    
    # print(Foo.test)
    
    Foo.test(1)
    
    <class '__main__.Foo'> 1
    

      

    __str__的用法

    必须返回字符串

    更正以后:

    打印对象会触发类的str方法。

    str小结:

    定义在类内部,必须返回一个字符串类型;

    什么时候会触发它的执行呢?

    打印由这个类产生的对象时,会触发执行

    Str和classmethod应用场景

    import time
    
    class Date:
    
        def __init__(self,year,month,day):
    
            self.year=year
    
            self.month=month
    
            self.day=day
    
        @classmethod#绑定到子类
    
        def now(cls):#用Date.now()的形式去产生实例,该实例是当前的时间
    
            t=time.localtime()#获取结构式的时间格式
    
            return cls(t.tm_year,t.tm_mon,t.tm_mday)#新建实例并返回
    
     
    
        @classmethod#绑定到子类
    
        def tomorrow(cls):#用Date.now()的形式去产生实例,该实例是明天的时间
    
            t=time.localtime(time.time()+86400)
    
            return cls(t.tm_year,t.tm_mon,t.tm_mday)
    
     
    
    class EuroDate(Date):
    
        def __str__(self):# 打印由这个类产生的对时,会触发执行
    
            return "年:%d,月:%d,日:%d"%(self.year,self.month,self.day)
    
    e1=EuroDate.now()
    
    print(e1)
    

      

  • 相关阅读:
    0541-leetcode算法实现之反转字符串II-reverseStrII-python&golang实现
    helm 入门简介与安装(1)
    ubuntu18.04 netplan 设置dns,dns不生效
    服务器报错WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
    0344-leetcode算法实现之反转字符串-reverse-string-python&golang实现
    python os模块常用方法总结
    0076-leeycode算法实现之最小覆盖子串-minimum-window-substring-python&golang实现
    0904-leetcode算法实现之水果成篮-fruit-into-baskets-python&golang实现
    0209-leetcode算法实现之长度最小子数组-minimum-size-subarray-sum-python&golang实现
    0977-leetcode算法实现之有序数组的平方sqaure-of-a-sorted-array-python&golang实现
  • 原文地址:https://www.cnblogs.com/asaka/p/6758503.html
Copyright © 2011-2022 走看看