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

2019-08-17  本文已影响0人  平知
章节号 内容            
1图片格式(png) 宽度大于620px,保持高宽比减低为620px
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

  ↓方法名前带有__的

    def __pri(self):
        print(self.int2)  
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、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

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的用法。
  使用的目的:这个方式可以极大简化对私有属性的访问。

  ↓第一步,把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章节  迭代器

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

In [53]: from collections import Iterable
In [55]: isinstance("abc",Iterable)
Out[55]: True

  可以被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: 
上一篇下一篇

猜你喜欢

热点阅读