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))

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

就是这样了,晚安。

 

posted @ 2020-03-15 00:56  崆峒山肖大侠  阅读(244)  评论(0编辑  收藏  举报