zoukankan      html  css  js  c++  java
  • python学习笔记整理(一)

      1 '''
      2 类和对象
      3 类其实就是模板,对象就是通过模板造出来的看得见摸得着的东西,
      4 如通过图纸造飞机,通过月饼模子印月饼。
      5 类Class的组成:
      6 1、类的名称:类名
      7 2、类的属性:一组数据,变量
      8 3、类的方法:进行操作的方法或行为
      9 如人类,身高年龄是人的属性,吃喝拉撒是行为
     10 
     11 
     12 '''
     13 
     14 class P:
     15     def eat(self):
     16         print("在吃东西。。。")
     17     def introduce(self):
     18         print("%s的年龄是:%s"%(self.name,self.age))
     19     def print_self(self):
     20         print(self)
     21 
     22 # 创建对象 
     23 tom = P() 
     24 # tom这个对象保存的是一串内存地址。
     25 print(tom) # <__main__.P object at 0x0000023433CFEB00>
     26 #调用对象里的方法
     27 tom.eat() 
     28 # python内存分析: https://zhuanlan.zhihu.com/p/59599988
     29 # 给对象添加属性
     30 tom.name = "汤姆"
     31 tom.age = 18
     32 tom.introduce()
     33 
     34 # 注意:
     35 # 在类中定义的方法默认是实例方法,该方法与普通的函数只有一个区别,那就是他们必须要
     36 # 有一个额外的第一参数,该参数保存的是类的实例化对象在计算机中的内存地址,通常被命名为self,也可以是其他名。
     37 # 没有self参数的话,调用方法时会报错:takes 0 positional arguments but 1 was given
     38 tom.print_self() #<__main__.P object at 0x000001D6BD4A1F28>
     39 # 相当于tom.introduce(tom)
     40 
     41 
     42 # __init__(self)方法
     43 # 初始化方法,当类中有init方法时,在创建类的对象的时候会python会自动调用
     44 # init方法,并把对象的引用(内存地址)传进去。在这个方法里面就可以直接初始化
     45 # 一些属性,而不用在外面去添加了。在创建对象的时候直接把属性值通过参数传进来
     46 
     47 
     48 class P1:
     49     def __init__(self,name,age):
     50         self.name = name
     51         self.age = age
     52 
     53     def __str__(self):
     54         return "哈哈哈"
     55     def introduce(self):
     56         print("%s的年龄是:%s"%(self.name,self.age))
     57     
     58 lyf = P1("刘亦菲",22)
     59 lyf.introduce() #刘亦菲的年龄是:22
     60 
     61 # __str__(self)方法
     62 # 当直接打印对象的时候,得到的是一个内存地址,当类中有str方法时,再去打印对象
     63 # 得到的是str方法中return的值。
     64 print(lyf) #哈哈哈
     65 
     66 # 延伸:以前多个函数可以共用一个全局变量,现在一个对象里面的多个方法可以共用一个属性,
     67 # 感觉对象就是把全局变量和函数打个包,多个对象就打多个包,直接互不影响。
     68 
     69 
     70 # 隐藏属性
     71 # 保护属性安全,即不能随意修改,一般处理方法为:1、将属性定义为私有属性;2、添加一个可调用的方法
     72 #  
     73 # 直接对属性赋值可能会出现在代码语法上没问题,但在逻辑上行不通的问题。例如年龄
     74 # 被错误的设置成222岁。可以在类里通过方法对传入的参数进行判断。
     75 
     76 class P2:
     77 
     78     def set_age(self,age):
     79         if age>0 and age<=100:
     80             self.age = age
     81         else:
     82             self.age = "年龄不合法"
     83 
     84     def get_age(self):
     85         return self.age
     86     
     87 lyf = P2()
     88 lyf.set_age(222)
     89 age = lyf.get_age()
     90 print(age) #年龄不合法
     91 
     92 
     93 #私有方法
     94 #当某个核心方法不想被外界直接调用,可以将此方法变为私有方法。再通过其他方法间接调用。
     95 class P3:
     96     # 私有属性
     97     def __init__(self,name,age):
     98         self.name = name
     99         self.__age = age
    100     # 私有方法
    101     def __get_money(self):
    102         print('正在取钱')
    103     # 公有方法
    104     def get_money(self,password):
    105         ''' 通过判断后决定是否调用私有方法'''
    106         if password==123456: 
    107             self.__get_money()
    108             print(self.__age) #调用私有属性
    109         else:
    110             print("密码错误")
    111 
    112 lyf=P3("刘亦菲",22)
    113 lyf.get_money(123) #密码错误
    114 lyf.get_money(123456)  #正在取钱
    115 print(lyf.name)  # 刘亦菲
    116 # print(lyf.__age) 报错
    117 
    118 # __del__(self)方法
    119 # 如果对象的引用计数变为0,就会自动调用__del__()方法
    120 # getrefcount()方法可以查看引用计数
    121 import sys
    122 class P4:
    123     def __del__(self):
    124         print("over")
    125 
    126 p1 = P4()
    127 p2 = p1
    128 print(sys.getrefcount(p1))# 3,该方法本身有一个变量接收对象,所以引用计数多1
    129 print(p1,p2)
    130 # 此时对象的引用计数为2,p1p2保存的是同一个地址。
    131 del p1
    132 #删除p1,引用计数变为1,对象还存在
    133 print(p2)
    134 del p2
    135 #删除p2,引用计数为0,对象在系统中被删除,内存释放,此时执行类里面的__del__()
    136 print("这句话出现在over后面")
    137 
    138 
    139 # 继承
    140 # 类可以继承自另一个类,继承是一种创建新的类的方式,可以减少代码冗余、提高重用性
    141 # 如果一个类没有继承任何类,则默认继承object类。
    142 class Fu(object):
    143     a=1
    144     print("我是父类,我继承自基类")
    145 #注意:类在定义的时候就执行类体代码,执行顺序是从上到下
    146 class Zi(Fu):
    147     def zi(self):
    148         print("我是子类,我继承自父类")
    149 
    150 
    151 class Sun(Zi):
    152     def sun(self):
    153         print("我是孙子类,我继承自子类")
    154 sun = Sun()
    155 print(sun.a) # 1
    156 sun.zi() #我是子类,我继承自父类
    157 
    158 
    159 # 重写
    160 # 当子类出现了跟父类同名的属性和方法时,优先调用子类的
    161 class Dog:
    162     a=1
    163     def eat(self):
    164         print("吃骨头")
    165 
    166 class Uzi(Dog):
    167     a=2
    168     def eat(self):
    169         print("uzi不吃骨头")
    170         # Dog.eat(self)    
    171 
    172 uzi = Uzi()
    173 uzi.eat()  #uzi不吃骨头
    174 print(uzi.a) #2
    175 # 如果非要调用Dog类的eat该怎么办呢?
    176 # 调用被重写的方法:
    177 # 1、类名.方法名(self)
    178 # 2、super().方法名()
    179 class Animal:
    180     def eat(self):
    181         print("吃东西")
    182 
    183 class Dog(Animal):
    184     a=1
    185     def eat(self):
    186         print("吃骨头")
    187 
    188 class Uzi(Dog):
    189     a=2
    190     def eat(self):
    191         print("uzi不吃骨头")
    192         Dog.eat(self)
    193         Animal.eat(self)
    194         super().eat()    
    195 uzi = Uzi()
    196 uzi.eat()
    197 
    198 # 注意,用类名.方法名(self)有弊端,假如类名改了,那继承自它的所有类调用时都需要修改类名,
    199 # 很麻烦。并且在多继承下还会出现重复调用的问题。这时候用super()就好了。
    200 
    201 
    202 # 私有方法和属性的继承
    203 class A:
    204     def __init__(self):
    205         self.num1 = 1
    206         self.__num2 = 2
    207     def test1(self):
    208         print("test1")
    209     def __test2(self):
    210         print("test2")
    211     def test3(self):
    212         self.__test2()
    213         print(self.__num2)
    214 
    215 
    216 class B(A):
    217     def test4(self):
    218         self.__test2()
    219         print(self.__num2)
    220 
    221 
    222 b=B()
    223 b.test3()
    224 # b.test4()
    225 # b.__test2()
    226 
    227 # 私有方法和属性不会被继承,子类中的方法不能调用父类的私有方法和私有属性,父类的方法
    228 # 可以直接调用私有方法和私有属性。
    229 
    230 
    231 
    232 # 多继承
    233 class Base(object):
    234     def test(self):
    235         print("base")
    236 class A(Base):
    237     def test(self):
    238         print("A")
    239 class B(Base):
    240     def test(self):
    241         print("B")
    242 class C(object):
    243     def test(self):
    244         print("C")
    245 class D(A,B,C):
    246     def test(self):
    247         print("D")
    248 
    249 d = D()
    250 d.test() # D
    251 print(D.__mro__) # 类名.__mro__ :查看调用方法的顺序
    252 # (<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, 
    253 # <class '__main__.Base'>, <class '__main__.C'>, <class 'object'>)
    254 
    255 
    256 
    257 
    258 # 多态
    259 # 多态是建立在继承和重写的基础上的。
    260 # 面向对象三要素:封装继承多态
    261 class A(object):
    262     def print_self(self):
    263         print("====A====")
    264 
    265 
    266 class B(A):
    267     def print_self(self):
    268         print("====B====")
    269 
    270 class C(object):
    271     def print_self(self):
    272         print("====C====")
    273 
    274 def test(obj):
    275     obj.print_self()
    276 a=A()
    277 b=B()
    278 c=C()
    279 test(a)
    280 test(b)
    281 test(c)
    282 '''
    283 定义test函数的时候并未声明传入的是什么类型的参数,不过只要传入的实例对象
    284 里面有print_self方法即可,不管他是A类型还是A的子类B类型还是C类型。在真正调用
    285 的时候才会确定实际的类型。这就是多态的体现。即见人说人话见鬼说鬼话。
    286 注意:当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型
    287 和Python自带的数据类型,比如str、list、dict没什么两样。
    288 '''
    289 print(type(a)) # <class '__main__.A'>
    290 print(type(c)) # <class '__main__.C'>
    291 
    292 
    293 
    294 # 实例属性和类属性
    295 class Dog(object):
    296     a = 1
    297     __b = 2
    298     def __init__(self,name):
    299         self.name = name
    300 
    301 
    302 d=Dog("zw") # 创建实例对象
    303 print(d.a) # 因为实例对象没有属性a,所以用到类对象的属性a
    304 print(Dog.a) #直接调用类的属性
    305 d.a = 18  # 给实例对象添加实例属性a
    306 print(d.a) # 实例对象有属性a则不用类属性a
    307 print(Dog.a) # 类属性a不变,还是1
    308 Dog.a = 11  # 修改类属性
    309 print(Dog.a) # 11
    310 
    311 '''
    312 总结:
    313 实例属性属于实例对象所有,各实例对象之间互不干扰;
    314 类属性属于类对象所有,所有实例对象共享类属性;
    315 取名时尽量避免实例属性和类属性重名。
    316 '''
    317 
    318 # 类方法、实例方法、静态方法
    319 
    320 # 对类属性进行操作常用到类方法
    321 # 为避免代码中函数和类并存的乱象,将普通函数转为静态方法放到类里面
    322 
    323 class Test(object):
    324     num = 0
    325     # 实例方法
    326     def __init__(self):
    327         pass
    328 
    329     # 类方法,加装饰器
    330     @classmethod
    331     def modify_num(cls):
    332         cls.num+=100
    333 
    334     # 静态方法,加装饰器
    335     @staticmethod
    336     def sta():
    337         print("hahahhahahah")
    338 
    339 t = Test()
    340 # 直接通过类名调用类方法:
    341 Test.modify_num() 
    342 print(Test.num) # 100
    343 # 通过类创建出来的对象调用类方法:
    344 t.modify_num()
    345 print(Test.num) # 200
    346 
    347 #调用静态方法:两者都行
    348 Test.sta()
    349 t.sta()
    350 
    351 
    352 
    353 # __new__(cls)方法
    354 
    355 class Test(object):
    356     def __init__(self):
    357         pass
    358 
    359     def __new__(cls): # 此处接收的实参为类对象的引用
    360         return object.__new__(cls)
    361         # 调用基类的new方法来创建实例对象
    362 
    363 print(id(Test))
    364 t=Test()
    365 print(id(t))
    366 '''
    367 程序从上往下:
    368 1、先创建一个类对象,Test存引用;
    369 2、执行 Test(),传入实参Test引用,调用__new__方法来创建实例对象,
    370     返回实例对象的引用;
    371 3、执行__init__方法,传入实例对象的引用;
    372 
    373 创建和初始化两个方法合起来相当于Java里面的构造方法。
    374 '''
    375 
    376 # 单例
    377 # 做到类的实例对象只创建一次
    378 # 让类属性保存第一次创建的实例的引用,以后每次调用new方法都不会去创建新的实例,
    379 # 而是返回第一次的实例
    380 class Dog(object):
    381     __instance = None
    382     def __new__(cls):
    383         if cls.__instance == None:
    384             cls.__instance = object.__new__(cls)
    385             return cls.__instance
    386         else:
    387             return cls.__instance
    388 
    389 a = Dog()
    390 print(id(a))  #2884513002720
    391 b = Dog()
    392 print(id(b))  #2884513002720
    393 
    394 # 单例初始化
    395 
    396 class Dog(object):
    397     __instance = None
    398     def __new__(cls,name):
    399         # 这个形参name别忘了,虽然用不到
    400         if cls.__instance == None:
    401             cls.__instance = object.__new__(cls)
    402             return cls.__instance
    403         else:
    404             return cls.__instance
    405     def __init__(self,name):
    406         self.name = name
    407 
    408 a=Dog("张三")
    409 print(a.name) #张三
    410 b=Dog("李四")
    411 print(b.name) #李四
    412 print(a.name) #李四  每次初始化覆盖上次的实例属性的值
    413 
    414 # 只初始化一次
    415 class Dog(object):
    416     __instance = None
    417     __init_flag = False
    418     def __new__(cls,name):
    419         # 这个形参name别忘了,虽然用不到
    420         if cls.__instance == None:
    421             cls.__instance = object.__new__(cls)
    422             return cls.__instance
    423         else:
    424             return cls.__instance
    425     def __init__(self,name):
    426         if Dog.__init_flag == False:
    427             self.name = name
    428             Dog.__init_flag = True
    429 
    430 a=Dog("张三")
    431 print(a.name) #张三
    432 b=Dog("李四")
    433 print(b.name) #张三
    434 
    435 
    436 # 异常处理
    437 try:
    438     #这里输入有潜在异常的代码,要有针对性
    439     1/0
    440     print(wy)
    441     
    442 except(NameError,FileNotFoundError):
    443     print("捕获到这两种异常后的处理操作。。。")
    444 except Exception as err_message:
    445     print("这里可捕获除上面两个之外的所有异常。。。")
    446     print(err_message) # 输出原来的异常信息
    447 else:
    448     print("没有异常才会执行这个")
    449 finally:
    450     print("无论有没有异常都会执行finally")
    451 
    452 # 出现1/0的异常后立马执行Exception,然后finally,print(wy)不会执行。
    453 # Exception是所有异常的基类
    454 
    455 # 异常传递
    456 def test1():
    457     print(haha)
    458 
    459 def test2():
    460     try:
    461         test1()
    462     except Exception as a:
    463         print("处理异常")
    464         print(a)  # name 'haha' is not defined
    465 
    466 test2() 
    467 
    468 
    469 # 自定义异常并抛出异常 
    470 """
    471 class InputException(Exception):
    472     ''' 自定义异常类,继承自异常基类Exception'''
    473     def __init__(self,age,max_age):
    474         self.age = age
    475         self.max_age = max_age
    476 
    477 class Test(object):
    478     def __init__(self,switch): # 异常处理开关
    479         self.switch = switch
    480     def handle(self):
    481         try:
    482             age = input("请输入你的年龄:")
    483             if int(age)>=120:
    484                 # 创建自定义异常类的实例对象,传参,抛出自定义异常
    485                 raise InputException(age,120) 
    486 
    487         except InputException as result: 
    488             ''' 捕获异常,将实例对象的引用存入到变量result '''
    489             if self.switch:
    490                 print("InputException:输入的年龄%s不在合理范围之内,最大为%d"%(result.age,result.max_age))
    491             else:
    492                 print("异常捕获开关已关闭")
    493 t1=Test(False)
    494 t1.handle()
    495 t2=Test(True)
    496 t2.handle()
    497 """
    498 
    499 '''
    500 请输入你的年龄:150
    501 异常捕获开关已关闭
    502 请输入你的年龄:150
    503 InputException:输入的年龄150不在合理范围之内,最大为120
    504 '''
    505 
    506 # 模块
    507 
    508 '''
    509 # 新建一个mod1.py文件,里面代码如下:
    510 def test1():
    511     print("这是mod1模块里的test1函数体")
    512 
    513 print(__name__)
    514 if __name__ == "__main__":
    515     test1()
    516 
    517 '''
    518 import mod1   # 导入新建的模块
    519 mod1.test1()
    520 
    521 # __name__方法:
    522 # 当自己调用自己时,__name__ == "__main__";
    523 # 当其他模块调用自己时,__name__ == "自己模块名"
    524 
    525 # 模块导入方式
    526 
    527 # 1、import 模块名   调用:模块名.函数名()
    528 # 2、from 模块名 import 函数名  调用:函数名()
    529 # 注意:from xxx import * ----此方式只能导入公有的属性、方法、类,
    530 # 无法导入以单下划线开头(protected)或以双下划线开头(private)的属性、方法、类,
    531 # 加了all变量可以实现非公有属性方法类的导入
    532 
    533 '''
    534 # 模块 mod2.py
    535 
    536 __all__ = ['a','__a',"__test4",'_A']
    537 
    538 # public变量
    539 a = 100
    540 # protected变量
    541 _a = 200
    542 # private变量
    543 __a = 300
    544 
    545 def test2():
    546     print("这是mod2模块里的test2函数体")
    547 def _test3():
    548     print("这是mod2模块里的test3函数体")
    549 def __test4():
    550     print("这是mod2模块里的test4函数体")
    551 
    552 
    553 class A:
    554     def pri(self):
    555         print("这是类A")
    556 class _A:
    557     def pri(self):
    558         print("这是类_A")
    559 class __A:
    560     def pri(self):
    561         print("这是类__A")
    562 
    563 '''
    564 # __all__变量
    565 # 模块里加入__all__变量,表示用from...import * 导入时只能导入all
    566 # 里面保存的对象,防止导入不需要的东西。没有all则会导入所有公有的属性方法类
    567 
    568 
    569 #
    570 # 包:多个模块放在同一个文件夹下(其中包含初始化模块),则该文件夹就成了一个包。
    571 # 在包的__init__.py模块里面的__all__变量还决定着包里的哪些模块可以被外界调用
    572 '''
    573 注意:多种导入方式的区别
    574 1、用from packag import * 这种方式只能从包里面导入__init__.py中__all__变量
    575 保存的模块,其他模块无法导入。
    576 2、from packag import module,调用时用module.method()
    577 3、可以用from packag.packag2.module import * 从包下面的指定模块里导入所有,
    578 这种导入方式不需要在__init__.py中指定模块名。
    579 4、import packag.module,调用时用packag.module.method()
    580 
    581 个人建议用第二种方式最好。
    582 
    583 个人建的包是无法在python交互式模式下导入的,若想在交互模式下使用,则应该构建发布模块。
    584 具体的发布过程见另一篇博客:https://www.cnblogs.com/wangyi0419/p/12495814.html
    585 '''
    586 
    587 
    588 # 导入模块的搜索路径
    589 # 在python中导入自己的模块时有时导不进来,可以在sys.path中添加自己模块的路径,这样
    590 # python就能够找到了。
    591 import sys
    592 a = sys.path
    593 print(a)
    594 '''
    595 [
    596 'C:\develop\sublime2020\python_file', 
    597 'C:\develop\devesoftware\python3.7\python37.zip', 
    598 'C:\develop\devesoftware\python3.7\DLLs', 
    599 'C:\develop\devesoftware\python3.7\lib', 
    600 'C:\develop\devesoftware\python3.7', 
    601 'C:\develop\devesoftware\python3.7\lib\site-packages'
    602 ]'''
    603 # sys.path.append("个人路径") 添加
    604 
    605 
    606 # 列表生成式
    607 # 
    608 a=[i for i in range(2,8)]
    609 print(a)
    610 a=list(range(1,10))
    611 print(a)
    612 a=[i*j for i in range(1,5) for j in range(1,5)]
    613 print(a)
    614 
    615 # 输出九九乘法表
    616 print('
    '.join([' '.join(['%s*%s=%-2s '%(j,i,j*i) for j in range(1,i+1)])for i in range(1,10)]))
    617 
    618 a = [i if i%2==0 else -i for i in range(1,11)]
    619 print(a) #[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
    620 a = [i  for i in range(1,11) if i%2==0 ]
    621 print(a) #[2, 4, 6, 8, 10]
    622 # 注意:
    623 # 第一个if...else...是表达式,写在for前面;
    624 # 写在for后面的if是过滤条件,不能带else
    625 
    626 
    627 
    628 # 字典生成式
    629 cook_str='BIDUPSID=D0727533D7147B7;PSTM=1530348042;BAIDUID=B1005C9BC2EB28'
    630 dic = {i.split('=')[0]:i.split('=')[1] for i in cook_str.split(";")}
    631 print(dic) 
    632 #{'BIDUPSID': 'D0727533D7147B7', 'PSTM': '1530348042', 'BAIDUID': 'B1005C9BC2EB28'}
    633 
    634 
    635 
    636 # 模块循环导入
    637 # 在a模块中导入b模块,在b模块中又导入了a模块,这就是循环导入,陷入死循环了,无解。
    638 # 在程序设计中要避免出现这种情况,设计上分层,降低耦合。
    639 
    640 
    641 # 集合
    642 # set,{},集合里的元素不会重复
    643 a=[1,2,3,2,1]
    644 # 怎么对列表a去重呢?
    645 # 方法一
    646 b=[]
    647 for i in a:
    648     if i not in b:
    649         b.append(i)
    650 print(b) # [1, 2, 3]
    651 # 方法二
    652 s = set(a)
    653 print(s) # {1, 2, 3}
    654 L = list(s)
    655 print(L) # [1, 2, 3]
    656 
    657 
    658 
    659 # == 和is
    660 # is 是比较两个引用是否指向了同一个对象(引用比较)。
    661 # == 是比较两个对象是否相等。
    662 a=1.1
    663 b=1.1
    664 print(a is b) # False
    665 print(a==b) #  True
    666 a=[1]
    667 b=[1]
    668 print(a is b) # False
    669 print(a==b) # True
    670 a=100
    671 b=100
    672 print(a is b) #  True
    673 
    674 # 为什么这个是true呢?到底哪些数字不会新建对象?
    675 # 写个程序测一下:
    676 a = 1
    677 b = 1
    678 while id(a) == id(b):
    679     a+=1
    680     b+=1
    681 print(a-1) # 256
    682 
    683 a = 1
    684 b = 1
    685 while id(a) == id(b):
    686     a-=1
    687     b-=1
    688 print(a+1) # -5
    689 # 发现只有-5 到 256这之间的整数才不会新建对象,is的结果是true。
    690 
    691 a=555
    692 b=555
    693 print(a is b) # False
    694 
    695 
    696 # 关于变量
    697 '''
    698 1、Python的变量创建过程是在代码第一次给他赋值就创建了变量,
    699 之后的赋值会改变已经创建的变量名的值;
    700 2、Python的变量是没有类型的,变量是通用的,只是在一个特定的时间点,
    701 引用了一个特定的对象;
    702 3、Python中 使用变量的时候,当变量出现在表达式中时,它会马上被所引用的对象所替代。
    703 '''
    704 
    705 # 深拷贝和浅拷贝
    706 import copy
    707 a = [1,2,3]
    708 b = [4,5,6]
    709 c=[a,b]
    710 d=c # 赋值,
    711 e=copy.copy(c) # 浅拷贝,e和c指向不同内存,但是内部元素指向相同
    712 f=copy.deepcopy(c) # 深拷贝,即递归拷贝,拷贝一切,f指向新的内存
    713 a.append('haha')
    714 print(c) # [[1, 2, 3, 'haha'], [4, 5, 6]]
    715 print(e) # [[1, 2, 3, 'haha'], [4, 5, 6]]
    716 print(f) # [[1, 2, 3], [4, 5, 6]]
    717 print(id(c))
    718 print(id(e))
    719 print(id(f))# 三个不同的地址
    720 
    721 # 深浅拷贝是对于可变类型对象而言的,不可变类型对象在python中没有拷贝一说。
    722 a = (1,2)
    723 b = a
    724 c = copy.copy(a)
    725 d = copy.deepcopy(a)
    726 print(id(a)) # 三个地址相同
    727 print(id(c))
    728 print(id(d))
    729 
    730 # 私有化
    731 
    732 # 给实例对象添加与私有属性同名的公有属性
    733 class Test(object):
    734     def __init__(self):
    735         self.__a = 1
    736         self.b=2
    737     def get(self):
    738         print(self.__a)
    739         print(self.b)
    740 t=Test()
    741 t.__a = 10 
    742 t.b=20
    743 print(t.__a)
    744 print(t.b)
    745 t.get()
    746 
    747 
    748 # property
    749 # 正常情况下通过set设置私有属性的值,get来获取值,不让外界直接获取,同时设置的
    750 # 时候也会对传入的实参进行必要的判断
    751 class Goddess(object):
    752     def __init__(self):
    753         self.__age = 22
    754     
    755     def get_age(self):
    756         return self.__age
    757     def set_age(self,age):
    758         if age>=30 or age<=18:
    759             print("年龄不在合理区间内")
    760         else:
    761             self.__age = age
    762             print("年龄已保存")
    763 
    764 g = Goddess()
    765 print(g.get_age()) # 22
    766 g.set_age(28) # 年龄已保存
    767 print(g.get_age()) # 28
    768 
    769 
    770 # 但这种做法每次都要调用set、get函数,稍微有点麻烦。可以通过property封装实现
    771 # 像修改公有属性那样的用对象.属性名直接修改私有属性。
    772 class Goddess(object):
    773     def __init__(self):
    774         self.__age = 22
    775     
    776     def get_age(self):
    777         return self.__age
    778     def set_age(self,age):
    779         if age>=30 or age<=18:
    780             print("年龄不在合理区间内")
    781         else:
    782             self.__age = age
    783             print("年龄已保存")
    784     age = property(get_age,set_age) # 这里的变量名age可以随意取
    785 g = Goddess()
    786 g.age = 25 # 相当于 g.set_age(25)
    787 print(g.age) # 25 ,相当于 g.get_age()
    788 
    789 # property的第二种实现方式:装饰器
    790 # 这里的set和get方法都要使用同一个名字age
    791 # 
    792 class Goddess(object):
    793     def __init__(self):
    794         self.__age = 22
    795 
    796     @property
    797     def age(self):  
    798         return self.__age
    799 
    800     @age.setter
    801     def age(self,age):
    802         if age>=30 or age<=18:
    803             print("年龄不在合理区间内")
    804         else:
    805             self.__age = age
    806             print("年龄已保存")
    807 
    808 g = Goddess()
    809 g.age = 27 # 调用第一个age方法
    810 print(g.age) # 27 调用第二个age方法
    811 
    812 # 元组的标志是逗号,而不是小括号。
  • 相关阅读:
    系统管理指南:基本管理 第12 章• x86: 引导系统(任务)
    系统管理指南:基本管理 第16 章• 管理软件(概述)
    排序 从小到大。
    系统管理指南:基本管理 第10 章• SPARC: 引导系统(任务)
    系统管理指南:基本管理 第11 章• x86: 基于GRUB 的引导(任务)
    系统管理指南:基本管理 第13 章• 引导过程(参考)
    排序 自己选择是从小到小还是从小到大排序。
    系统管理指南:基本管理 第15 章• 管理服务(任务)
    .NET反射的简单理解
    SQL分页存储过程
  • 原文地址:https://www.cnblogs.com/wangyi0419/p/12489068.html
Copyright © 2011-2022 走看看