章节号 | 内容 |
---|---|
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:
网友评论