• Python之旅的第3*7天(静态属性、类方法、静态方法、组合)


           已经21天了,其实想感叹一下的,但是想起再没开始学之前,一位业界大神告诉我,你想学Python,以你的智商,一个周就能走上编程之路了,现在才发现,都是扯犊子啊。路只有自己走了才知道深浅,肉也只有长到自己身上了才知道我现在到底有多胖,不多说,省钱买新衣服吧。

      今天主要讲的是类(class)的静态属性、类方法、静态方法和组合,应该算是功能的延伸吧,今天都是一些基础的引入。

      一、静态属性的引入

    # 关于静态属性的引入
    # class Dog:
    #     '引入静态属性的一个测试类'
    #     type = '小土狗'
    #     def __init__(self, name, gender, age):
    #         self.name = name
    #         self.gender = gender
    #         self.age = age
    #
    #     def yaoren(self):
    #         print('%s正在咬人'%self.name)
    
    # 首先我们先生成一个实例对象
    # p1 = Dog('alex','women',18)
    # 我们用p1去调用Dog类的数据属性,也就是type = '小土狗'
    # print(p1.type)
    # 而我们在调用yaoren这个功能属性的时候往往是这样的
    # p1.yaoren()
    # 那么我们在后面运行的时候,通过调用的语句就能看出他到底是一个什么属性
    # 这种情况是不利于软件封装的,因为在实际运用的过程中,yaoren其实也是一个固有的属性
    # 而后面的括号,和直接运行的情况,很明显的将两者区分开了
    # 这个时候我们引入了@property
    # 使用方法如下
    
    class Dog:
        '引入静态属性的一个测试类'
        type = '小土狗'
    
        def __init__(self, name, gender, age):
            self.name = name
            self.gender = gender
            self.age = age
        @property
        def yaoren(self):
            return '%s正在咬人' % self.name
            # print('%s正在咬人' % self.name)
    # 经过了@property的修饰后,书写的方式和修饰器一毛一样
    # 我们重新调用yaoren这个功能属性,方法就和调用数据属性的一样
    p1 = Dog('alex','women',18)
    print(p1.yaoren)
    print(p1.type)
    # 这样在完成封装之后就便于类的统一,从外面是完全看不出来的

      二、类方法

    # 下面是类方法
    # 换一个例子吧,就说一个智能手机的问题
    # class Phone:
         # '关于类方法的一个测试,前面我们在查看一个类的功能属性,也就是类下面的函数功能时候,
         # '往往都是先实例化一个类的实例,然后调用对应的功能属性'
    #     def __init__(self,pinpai, neicun, cpu):
    #         self.pinpai = pinpai
    #         self.neicun = neicun
    #         self.cpu    = cpu
    #
    #     def paizhao(self,xiangsu):
    #         print('%s的相机镜头用的是%s像素,拍照很厉害'%(self.pinpai,xiangsu))
    
    # 首先是我们的常规套路
    # 我们会先根据Phone类生成一个实例化的对象
    # 然后再去调用拍照的方法
    # p1 = Phone('小米','4G','骁龙865')
    # p1.paizhao('1亿')
    # 输出了:小米的相机镜头用的是1亿像素,拍照很厉害
    
    # 但是生活中往往有很多人,打死不说品牌,就问你智能手机拍照牛不牛逼
    # 反映到函数上就是,我们不生成一个实例化的对象,还能不能调用paizhao方法
    # 我们在实际写类里面的函数的时候,往往会直接将self作为默认参数传人
    # 所以,引入classmethod 将class作为默认参数传入
    
    class Phone:
         # '关于类方法的一个测试,前面我们在查看一个类的功能属性,也就是类下面的函数功能时候,
         # '往往都是先实例化一个类的实例,然后调用对应的功能属性'
        def __init__(self,pinpai, neicun, cpu):
            self.pinpai = pinpai
            self.neicun = neicun
            self.cpu    = cpu
    
        # @classmethod
        # def paizhao(self,xiangsu):
        #     print('%s的相机镜头用的是%s像素,拍照很厉害'%(self.pinpai,xiangsu))
        @classmethod
        def paizhao_test(cls,xiangsu):   #此时括号内的默认参数就是cls
            print('智能手机的相机镜头用的是%s像素,拍照很厉害' % ( xiangsu))
    
    
    # 增加了@classmethod之后我们就可以不生成实例化对象对拍照方法进行调用
    Phone.paizhao_test('1亿')
    p1 = Phone('小米','4G','骁龙865')
    p1.paizhao_test('1亿')
    # 同时实例对象也可以调用
    
    # 其实这个类的方法主要作用是用于显示类的信息
    # 这里就得提到关于面向对象的类和生活中的类,还是存在区别的
    # 显示类的信息就是程序员的编程需要
    
    class Phone1:
        # '关于类方法的一个测试,前面我们在查看一个类的功能属性,也就是类下面的函数功能时候,
        # '往往都是先实例化一个类的实例,然后调用对应的功能属性'
        def __init__(self, pinpai, neicun, cpu):
            self.pinpai = pinpai
            self.neicun = neicun
            self.cpu = cpu
    
        # @classmethod
        # def paizhao(self,xiangsu):
        #     print('%s的相机镜头用的是%s像素,拍照很厉害'%(self.pinpai,xiangsu))
        def paizhao_test(self, xiangsu):  # 此时括号内的默认参数就是cls
            print('智能手机的相机镜头用的是%s像素,拍照很厉害' % (xiangsu))
        @classmethod
        def tell_info(cls):
            return Phone1.__dict__
    # 类似是这样用的吧,我还是一直小菜鸡,说不清楚

    三、静态方法(这里的静态方法实质上就是类的一个工具包,他的参数和self没有任何关系)

    # 这里的静态方法实质上就是类的一个工具包,他的参数和self没有任何关系
    # 这个地方我觉的还是以手机为例
    # 引入静态方法的是增加@staticmethod
    class Telephone:
        '假设这是一个手机相关的类,但是诺基亚可以砸核桃'
        def __init__(self,name,xinghao):
            self.name = name
            self.xinghao =xinghao
        @staticmethod
        def zahetao():
            print('我们诺基亚我牛逼')
        def calling(self):
            print('%s的%s在打电话'%(self.name,self.xinghao))
    
    # 我们可以看到zahetao()这个功能属性其实并不需要传递self有关的参数
    Telephone.zahetao()
    # 用类去调用这个方法没有问题
    # p1 = Telephone('xiaomi','9se')
    # p1.zahetao()
    # 实例对象去调用也没有问题
    
    # 但是此时如果我们不在zahetao()函数前面增加@staticmethod,也不传递参数,和加了的有什么区别呢
    # 此时我隐去@staticmethod
    print(Telephone.__dict__)
    # 这个时候出现了一个问题
    # p1.zahetao()这句代码报错了,报错内容如下
    # zahetao() takes 0 positional arguments but 1 was given
    # 因为class会默认传递一个参数self,而我们的zahetao是不需要参数的
    # 所以报错了
    
    # 然后是关于此时Telephone的__dict__输出内容的问题
    # {'__init__': <function Telephone.__init__ at 0x00000272C9064840>, 'calling': <function Telephone.calling at 0x00000272C9064950>,
    # '__dict__': <attribute '__dict__' of 'Telephone' objects>, '__weakref__': <attribute '__weakref__' of 'Telephone' objects>,
    # 'zahetao': <function Telephone.zahetao at 0x00000272C90648C8>, '__doc__': '假设这是一个手机相关的类,但是诺基亚可以砸核桃','__module__': '__main__'}
    # 这里我们注意字典中关于 zahetao()函数的描述是function
    
    #然后我们重新增加上@staticmethod的修饰
    # {'calling': <function Telephone.calling at 0x000002D129824950>, '__weakref__': <attribute '__weakref__' of 'Telephone' objects>, 
    # 'zahetao': <staticmethod object at 0x000002D129827B70>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Telephone'
    # objects>, '__doc__': '假设这是一个手机相关的类,但是诺基亚可以砸核桃', '__init__': <function Telephone.__init__ at 0x000002D129824840>}
    # zahetao()函数的描述是staticmethod object
    # 所以发生了刚才p1调用失败的情况

    四、组合

      关于组合,其实就是将没有共同特点,但是又相关关联的类组合起来

    # 这里的特点就类似与组装一个机器人,各个部件生产好了,然后组装在一起
    # class Hand:
    #     pass
    #
    # class Foot:
    #     pass
    #
    # class Trunk:
    #     pass
    #
    # class Head:
    #     pass
    #
    #
    # class Person:
    #     def __init__(self,id_num,name):
    #         self.id_num=id_num
    #         self.name=name
    #         self.hand=Hand()
    #         self.foot=Foot()
    #         self.trunk=Trunk()
    #         self.head=Head()
    # p1=Person('111111','alex')
    
    
    # print(p1.__dict__)
    
    # class School:
    #     def __init__(self,name,addr):
    #         self.name=name
    #         self.addr=addr
    #
    #     def zhao_sheng(self):
    #         print('%s 正在招生' %self.name)
    #
    # class Course:
    #     def __init__(self,name,price,period,school):
    #         self.name=name
    #         self.price=price
    #         self.period=period
    #         self.school=school
    #
    #
    #
    # s1=School('oldboy','北京')
    # s2=School('oldboy','南京')
    # s3=School('oldboy','东京')
    #
    # # c1=Course('linux',10,'1h','oldboy 北京')
    # c1=Course('linux',10,'1h',s1)
    #
    # print(c1.__dict__)
    # print(c1.school.name)
    # print(s1)
    
    
    class School:
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
    
    
        def zhao_sheng(self):
            print('%s 正在招生' %self.name)
    
    class Course:
        def __init__(self,name,price,period,school):
            self.name=name
            self.price=price
            self.period=period
            self.school=school
    
    
    
    s1=School('oldboy','北京')
    s2=School('oldboy','南京')
    s3=School('oldboy','东京')
    
    # c1=Course('linux',10,'1h','oldboy 北京')
    # c1=Course('linux',10,'1h',s1)
    
    msg='''
    1 老男孩 北京校区
    2 老男孩 南京校区
    3 老男孩 东京校区
    '''
    while True:
        print(msg)
        menu={
            '1':s1,
            '2':s2,
            '3':s3
        }
        choice=input('选择学校>>: ')
        school_obj=menu[choice]
        name=input('课程名>>: ')
        price=input('课程费用>>: ')
        period=input('课程周期>>: ')
        new_course=Course(name,price,period,school_obj)
        print('课程【%s】属于【%s】学校' %(new_course.name,new_course.school.name))

    关于组合我理解的还是不够深刻,暂时先用这个了,明天我会增加自己的感悟的。

    就是这样了,晚安。

  • 相关阅读:
    oracle添加字段,备注
    oracle对日期date类型操作的函数
    查询效率例子收藏
    webuploader.min.js 简单例子
    select 数字/字符串/count(参数)/sum(数字) from table
    oracle常用分析函数 over(partition by xxx order by xxx)
    LigerUi遮罩的两个方法
    LigerUI子父窗口之间传参问题
    LigerUi自动检索输入
    LigerUi折叠与展开
  • 原文地址:https://www.cnblogs.com/xiaoyaotx/p/12495545.html
Copyright © 2020-2023  润新知