美文网首页
02Python学习笔记之二.三【私有化、property、迭代

02Python学习笔记之二.三【私有化、property、迭代

作者: 平知 | 来源:发表于2019-08-17 17:02 被阅读0次
    章节号 内容            
    1图片格式(png) 宽度大于620px,保持高宽比减低为620px
    1-1 应用
    1-1-1 方法

    第1章节  私有化

    • 1-1 私有化—私有属性

      ↓类的属性一旦添加了__就变为私有属性,无法在类外部的直接进行获取。同样这个类的子类也无法直接获取这个属性


      ↓但是也一定要注意分辨以下的情况:
    class test(object):
        def __init__(self, int1, int2):
          self.__int1 = int1
          self.int2 = int2
        
        def pri(self):
            print("我是类内部进行赋值的int1=",end="")
            print(self.__int1)
    
    
    
    t1=test(1000,2000)
    t1.pri()
    t1.__int1=9999
    print("我是外部赋值的int1=",end="")
    print(t1.__int1)
    t1.pri()
    
    我是类内部进行赋值的int1=1000
    我是外部赋值的int1=9999
    我是类内部进行赋值的int1=1000
    

      ↑请注意分析这里为什么不会报错。是因为在print(t1.__int1)执行前,t1.__int1=9999这句语句已经被执行了,这相当于给t1这个实体又添加了一个属性,这个属性的名字正好等于__int1,这和类原本定义的self.__int1不相同。从第二次t1.pri()调用但是结果没有变就能进行佐证。
      ↓一旦添加了__的属性,就要配套2个方法,一个用来get(),一个用来set()

    class test(object):
        def __init__(self, int1, int2):
          self.__int1 = int1
          self.int2 = int2
    
        def getn(self):
            return self.__int1
    
        def setn(self,int):
            self.__int1=int  
    
    t1=test(1000,2000)
    print(t1.getn())
    t1.setn(9999)
    print(t1.getn())
    
    1000
    9999
    
    • 1-2 私有化—私有方法

      ↓方法名前带有__的

        def __pri(self):
            print(self.int2)  
    
    • 1-3 私有化—私有化属性用不了的原因(ipython测试)

    In [36]: class test(object):
        ...:     def __init__(self):
        ...:         self.__num=100
        ...:         
    
    In [37]: t=test()
    
    In [38]: dir(t)
    Out[38]: 
    ['__class__',
     '__delattr__',
     '__dict__',
     '__dir__',
     '__doc__',
     '__eq__',
     '__format__',
     '__ge__',
     '__getattribute__',
     '__gt__',
     '__hash__',
     '__init__',
     '__init_subclass__',
     '__le__',
     '__lt__',
     '__module__',
     '__ne__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__setattr__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     '__weakref__',
     '_test__num']
    
    In [39]: 
    

      ↑注意最后一行,__num被改为了_test__num,这个方式叫做名字重整(name mangling)。就是为了避免子类意外重写父类的方法或者属性。

    In [43]: t._test__num
    Out[43]: 100
    

      ↑实际上这里还是访问到了。

    In [47]: class test(object):
        ...:     def __init__(self):
        ...:         self.__num=10
        ...:     def pri(self):
        ...:         print(self.__num)
        ...:         
        ...:     
    
    In [48]: t=test()
    
    In [49]: t.pri()
    10
    In [51]: t._test__num =1000
    
    In [52]: t.pri()
    1000
    

      ↑也一样修改掉了。
      o,fuck!

    • 1-4 私有化—下划线的用法

      1、XX 无下划线 公有变量
      2、_XX 单前置下划线  只能在一个模块的范围内使用

    假设一个模块内有一个变量 _number,这个模块叫test
    在另一个文件中:
    from test import *
    _number=10 
    #就会报错
    

      !但是!:

    import test
    test._number=10
    是可以正常使用的,因为test.限定了这个变量的范围,不易和其他冲突
    

      3、__XX 双前置下划线 私有
      4、__XX__ 双前、后置下划线 魔法方法或属性
      5、XX_ 单后置下划线 避免关键字冲突

    if_=12
    不要这么用!!!!
    

    第2章节  property

    • 2-1 property—用property升级set()get()方法

    class test(object):
        def __init__(self, int1=10, int2=20):
            self.__int1 = int1
            self.int2 = int2
    
        def getn(self):
            return self.__int1
    
        def setn(self, int):
            self.__int1 = int
    
    #注意这里
        num = property(getn,setn)
    #注意这里
    
    t=test()
    print(t.num)
    t.num=1000
    print(t.num)
    
    
    10
    1000
    

      ↑我的理解是property把set和get做了二次封装,因为这个property是有固定格式的,不可以乱来。VScode的python提示插件会提示这个property的用法。
      使用的目的:这个方式可以极大简化对私有属性的访问。

    • 2-2 property—第二种操作方法

      ↓第一步,把set和get方法名字改成一样的:

    class test(object):
        def __init__(self, int1=10, int2=20):
            self.__int1 = int1
            self.int2 = int2
        
    
        def intn(self):
            return self.__int1
    
    
        def intn(self, int):
            self.__int1 = int
    

      ↓第二步,在两个同名的方法上面开始加上装饰,不能乱加,要看方法的具体功能是什么。具体内容如下:

    class test(object):
        def __init__(self, int1=10, int2=20):
            self.__int1 = int1
            self.int2 = int2
    
        表示property的名字就叫做intn 
        @property   
        def intn(self):
            return self.__int1
    
    
        @intn.setter
        def intn(self, int):
            self.__int1 = int
    
    t=test()
    print(t.intn)
    t.intn=1000
    print(t.intn)
    
    10
    1000
    

      ↑具体功能和第一种方式一样。这里要使用谁作为属性,就看@property 下面的方法名叫什么。
      @property 声明2件事:1、下面这个方法名字就是外部使用的变量名。2、下面这个方法就是get方法

    第3章节  迭代器

    • 3-1 迭代器—可迭代对象

      可以用for循环来调用的的对象,例如:字符串、列表、元组、字典、set?。
      还有就是generator,包括生成器和带yield的generator function。
      如何判断那些对象可以迭代呢?

    In [53]: from collections import Iterable
    In [55]: isinstance("abc",Iterable)
    Out[55]: True
    
    • 3-2 迭代器—迭代器

      可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

    In [58]: from collections import Iterator
    
    In [59]: isinstance((x for x in range(10)),Iterator)
        ...: 
    Out[59]: True
    

      把list、dict、str等可迭代对象变成Iterator,可以使用iter()函数。

    In [60]: a=[1,2,3,4]
    
    In [61]: a
    Out[61]: [1, 2, 3, 4]
    
    In [78]: b=iter(a)
    
    In [79]: next(b)
    Out[79]: 1
    
    In [80]: next(b)
    Out[80]: 2
    
    In [81]: next(b)
    Out[81]: 3
    
    In [82]: next(b)
    Out[82]: 4
    
    In [83]: next(b)
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-83-adb3e17b0219> in <module>()
    ----> 1 next(b)
    
    StopIteration: 
    

    相关文章

      网友评论

          本文标题:02Python学习笔记之二.三【私有化、property、迭代

          本文链接:https://www.haomeiwen.com/subject/ikzhsctx.html