zoukankan      html  css  js  c++  java
  • Python之旅的第20天(class和实例对象)

    内功心法果然和基本功没关系,绕来绕去的确实很容易懵,所以今天内容其实不多,但是各种试错还是很多的

    一、class知识的继续补充

    关于class的一些应该说明的本质问题
    还是以狗狗为例
    class Dog:
        '这里一般放置关于这个类的描述,还是应该专业点,这是一个狗狗的类'
    
        def __init__(self, name, gender, age, type):
            self.name = name
            self.gender = gender
            self.age = age
            self.pinzhong = type
        __init__函数是不能又返回值的,如果你强行返回,系统会告诉你你错了
        没有return
    
        下面就可以定义一些关于狗的方法了
        def xiaogou(self):
            #这里你会发现当你定义了一个函数之后,class会自动要求把你在__init__中的self作为变量传输进去
            print('%s的狗才能生小狗'%self.gender)
    
        def jiao(self):
            print('%s正在汪汪汪叫'%self.name)
    
        def chishi(self):
            print('%s岁之后狗才会吃屎'%self.age)
    
        def yang(self):
            print('%s容易掉毛'%self.pinzhong)
    
    dog1 = Dog('旺财','woman','5','金毛')
    这里这句其实相当于在执行类Dog,输入参数的过程和函数没有区别
    上面这一句做的事情其实和下面这句是一样的
    dog1 = Dog.__init__(dog1,'旺财','woman','5','金毛')
    当你在执行Dog的时候其实就是__init__方法,他会默认将dog1传给self
    这一步就是对象的实例化的过程
    print(dog1)
    print(dog1.__dict__)
    {'pinzhong': '金毛', 'gender': 'woman', 'age': '5', 'name': '旺财'}
    你会发现当一个类实例化之后,功能属性(即函数)不在上述字典中
    但是Dog类里面还是在的哦
    print(Dog.__dict__)
    {'__module__': '__main__', 'chishi': <function Dog.chishi at 0x000001F3123A4598>,
    '__init__': <function Dog.__init__ at 0x000001F3123A40D0>, '__dict__': <attribute '__dict__' of 'Dog' objects>,
    '__doc__': '这里一般放置关于这个类的描述,还是应该专业点,这是一个狗狗的类', '__weakref__': <attribute '__weakref__' of
    'Dog'objects>, 'jiao': <function Dog.jiao at 0x000001F3123A4510>, 'yang': <function Dog.yang at 0x000001F3123A4620>,
    'xiaogou': <function Dog.xiaogou at 0x000001F3123A4488>}
    此时你是否看到,我们在输出对象的字典的时候是只有数据属性部分的
    那么如何调用功能属性呢
    先是使用老式方法开始
    Dog.__dict__['yang'](dog1)
    准确的输出了:金毛容易掉毛
    但是这种方法太low了,现在的class类可以帮我们实现
    dog1.yang()
    这里也是输出了:金毛容易掉毛
    但是你会发现,yang这个函数是需要你传递一个参数self的
    这里传递参数由class协助完成,会默认将__init__方法形成的对象传入其中
    如果使用老方法不传参数会怎样呢
    Dog.__dict__['yang']()
    这个时候就会报错:TypeError:yang() missing 1 required positional argument: 'self'
    说你没传参数
    还有就是关于class里面的作用域问题
    之前我们提到,如果个变量找不到自己的值,会不停往外找,直到找到为止,但是在class中
    如果找到class的最外层还没找到就不会找了
    重新来一个类验证一下吧
    
    dang = ''
    class Chinese:
        pep = ''
    print(Chinese.dang)  #输出:党
    但是我们把党注释掉,放到class外面
    print(Chinese.dang)
    此时会报错:AttributeError: type object 'Chinese' has no attribute 'dang'

    二、类的增删改查

    类的增删改查
    class Chinese:
        'Chinese类,增删改查测试'
        country = 'China'
        def __init__(self,name):
            self.xingming = name
    
        def play(self,ball):
            print('%s正在打%s'%(self.xingming,ball))
    
    类的增加,首先是数据属性的增加
    Chinese.goverment = '党'
    p1 = Chinese('alex')
    print(p1.country , p1.goverment)
    输出:China 党  完成增加新的数据属性的增加
    
    类的增加,关于增加功能属性的部分
    def test(self):
        print('这是测试部分的内容')
    Chinese.test_add = test
    p1.test_add()   #这是测试部分的内容
    
    删除类的功能,我们就删除掉上面刚才新增的类
    del Chinese.test_add
    del Chinese.goverment
    print(Chinese.__dict__)
    {'__init__': <function Chinese.__init__ at 0x00000200A8DC40D0>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>,
    'play': <function Chinese.play at 0x00000200A8DC4488>, 'country': 'China', '__doc__': 'Chinese类,增删改查测试',
    '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__module__': '__main__'}
    此时刚才新增的两个数据属性和功能属性就都删除掉了
    
    关于类的修改,其实修改的方式和新增的方式是类似的
    Chinese.country = '小日本'
    def eat_food(self , food):
        print('%s在吃 %s'%(self.xingming , food))
    Chinese.play = eat_food
    print(p1.country)   #输出:小日本
    p1.play('xiang')
    输出:alex在吃 xiang
    
    查看,就直接用类.属性名直接调用查看就可以了

    三、实例对象的增删改查

    # 实例对象的增删改查
    # class Dog:
    #     '测试实例对象的增删改查,包括他的功能属性的修改'
    #     def __init__(self,name):
    #         self.name = name
    #
    #     def wang(self,people):
    #         print('%s正在冲着%s汪汪叫'%(self.name , people))
    #
    # p1 = Dog('wangcai')
    # print(p1.name)  #wangcai
    # p1.name = '旺财'
    # print(p1.name)   #旺财
    
    # p1.wang('如花')  #旺财正在冲着如花汪汪叫
    # def yaoweiba(self , people):
    #     print('%s正在对着%s摇尾巴' % (self.name, people))
    # p1.wang = yaoweiba
    # p1.wang(p1,'如花') #旺财正在对着如花摇尾巴
    # 上面这一句需要注意的是,因为这里修改的是针对p1的功能属性,之前p1是没有功能属性的,他的功能属性是调用Dog类的功能属性
    # 这里进行修改之后,对类里面的功能并没有影响,所以新增的功能也不具备class优越性,所以我们不仅需要传递参数people,还需
    # 要传递参数self,此时我如果使用另一个对象实例去调用Dog的wang方法,结果还是之前的
    # p2 = Dog('小白')
    # p2.wang('美伢')   #小白正在冲着美伢汪汪叫
    # 所以针对实例对象的功能属性修改是没有实际意义的
    # 也不提倡使用

    四、接下来是些比较有意思的东西,看着蛮有意思的,但是想多了反而更容易错,先记录在这里吧

    # 下面是一些关于class模块和平时的局部作用域的奇葩案例,加深理解
    
    # country = '外国'
    # class China:
    #     country = '中国'
    #     def __init__(self,name):
    #         print(country)
    #         self.name = name
    #
    #     def kaixin(self):
    #         print('%s今天很开心'%s)
    #
    # p1 = China('马云')
    # 对China类进行实例化生成实例对象的过程中,在__init__函数下的print输出的country
    # 输出结果是'外国'
    # print(p1.country)   #而此处的country是中国
    
    # 上面这个例子就反应了一个问题,country = '中国' 是作为一个类的属性保存在China类中,如果我们以类名.属性名,
    # 或者实例对象.属性名调用时,会在China类中查看属性对应的值,而__init__中的print语句输出的country只是一个单
    # 纯的变量,虽然近在眼前的就是country = '中国'  但是,这部分是属于类的属性的
    
    # 下面是关于修改的范围
    # p2 = China('alex')
    # print(p2.country)
    # p2.country = '日本'
    # print('class的是',China.country)
    # print('实例对象',p2.country)
    # class的是 中国
    # 实例对象 日本
    # 可以明显看处p2.country修改了属性对class不会有任何影响
    
    # 接下来是一个比较狠的
    class Test:
        '测试类'
        a = ['a','b']
        def __init__(self,name):
            self.name = name
    
    p1 = Test('alex')
    # p1.a = ['a','b','c']
    print('实例对象',p1.a)
    print('Test类的',Test.a)
    # 实例对象 ['a', 'b', 'c']
    # Test类的 ['a', 'b']
    # 这样修改其实是相当于新建了一个p1.a的列表
    # 如果修改换种方式呢
    p1.a.append('c')
    print('实例对象',p1.a)
    print('Test类的',Test.a)
    # 实例对象 ['a', 'b', 'c']
    # Test类的 ['a', 'b', 'c']
    # 这里其实是直接在列表a上面进行修改,导致类的发生了变化

    今天的内容就是这些了,class部分告一段落,这个功能的确很强大,之前的内容完全都被他整合了。

    我擦,吐槽一下,敏感词汇,没想到这还有。。。

  • 相关阅读:
    6.Redis 哈希(Hash)的命令
    5.redis中String类型数据操作的命令
    4.redis中的key命令
    3.redis客户端连接服务器
    Bomblab
    leetcode multiply-strings
    datalab
    leetcode max-points-on-a-line
    os
    python 实现简单的端口扫描器
  • 原文地址:https://www.cnblogs.com/xiaoyaotx/p/12490213.html
Copyright © 2011-2022 走看看