zoukankan      html  css  js  c++  java
  • Python自动化开发课堂笔记【Day07】

    类与对象

    对象是特征(变量)与技能(函数)的结合体,类是一系列对象共有的特征与技能的结合体
      现实生活中:先有对象,再总结归纳出类
      程序中:一定是先定义类,再实例化出对象
    定义类的语法:
    class 类名:
      '''注释'''
      类体(可以是任意代码)

    1 class Chinese:
    2     country = 'China'
    3     def __init__(self,name,age):
    4         self.name = name
    5         self.age = age
    6         print('--->',self.name,self.age)
    7     def talk(self):
    8         print('say Chinese')

    1. 类的第一种用法,实例化

    1 p1 = Chinese('Albert',18)
    2 p2 = Chinese('Baker',33)

    2. 类的第二种用法,属性引用

    1 print(Chinese.country)#类的数据属性
    2 print(Chinese.__init__)#类的函数属性
    3 p1.__init__('Talbert',81)

      3. 其他知识点补充

     1 print(Chinese.__dict__)#查看类的属性字典,或者说是名称空间
     2 #{'__module__': '__main__', '__doc__': None, 'talk': <function Chinese.talk at 0x00675D68>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, 'country': 'China', '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__init__': <function Chinese.__init__ at 0x00675228>}
     3 print(Chinese.country)
     4 print(Chinese.__dict__['country'])#效果同上,本质上是如何取到的country这个变量
     5 print(p1.name,p1.age)
     6 print(p1.__dict__['name'],p1.__dict__['age'])
     7 
     8 #类型和类是统一的
     9 print(type(p1)) #<class '__main__.Chinese'>
    10 
    11 #类中定义的变量对象是公用的,不会产生新的内存空间
    12 print(id(p1.country)) #5593664
    13 print(id(p2.country)) #5593664
    14 print(id(Chinese.country)) #5593664

    类绑定方法(类实例化后绑定到对象身上)
    绑定方法:绑定到谁身上就是给谁用的,谁来调用就会自动把自己当作第一个参数传入

    1 print(Chinese.talk) #<function Chinese.talk at 0x006F5D68>
    2 print(p1.talk) #<bound method Chinese.talk of <__main__.Chinese object at 0x002759F0>>
    3 print(p2.talk) #<bound method Chinese.talk of <__main__.Chinese object at 0x0070EB50>>

    总结:定义在类内部的变量是所有对象共有的,id全一样。定义在类内部的函数,是绑定到所有对象的,是给对象来用的,obj.func()会把obj本身当作第一个参数传入
      print(p1.x) # p1.__dict__ ---> Chinese.__dict__ ---> 报错
    如果要查找一个属性,先从对象名称空间中查找,找不到之后再到类名称空间查找,如果还找不到不会再去全局找,直接报错

    练习:

     1 1.统计类实例化对象的次数
     2 class Chinese:
     3     country = 'China'
     4     count = 0
     5     def __init__(self,name,age):
     6         self.name = name
     7         self.age = age
     8         Chinese.count += 1 #类变量的概念
     9         print('--->',self.name,self.age)
    10         print('%d obj create' % Chinese.count)
    11 p1=Chinese('A',1)
    12 p2=Chinese('B',2)
    13 
    14 2.定义一个学生类
    15 class Stu:
    16     def __init__(self,stuid,name,age):
    17         self.stuid = stuid
    18         self.name = name
    19         self.age = age
    20         print('Student--->',self.stuid,self.name,self.age)
    21 s1 = Stu(1,'A',18)
    22 s2 = Stu(2,'B',18)
    23 
    24 3.类对象交互
    25 class A:
    26     camp = 'AAA'
    27     def __init__(self,nickname,damage=100, HP=200):
    28         self.nickname = nickname
    29         self.damage = damage
    30         self.HP = HP
    31     def attack(self,enemy):
    32         enemy.HP -= self.damage
    33         print('造成%d点伤害' % self.damage)
    34 class B:
    35     camp = 'BBB'
    36     def __init__(self,nickname,damage=200, HP=100):
    37         self.nickname = nickname
    38         self.damage = damage
    39         self.HP = HP
    40     def attack(self,enemy):
    41         enemy.HP -= self.damage
    42         print('造成%d点伤害' % self.damage)
    43 a1 = A('a1')
    44 b1 = B('b1')
    45 print(a1.camp)
    46 print(b1.camp)
    47 a1.attack(b1)
    48 b1.attack(a1)

    继承

      继承是一种创建新类的方式,新建的类可以继承一个或多个父类,父类又可以称为基类或超类,新建的类称为派生类或子类

    1 class ParentClass1:
    2     pass
    3 class ParentClass2:
    4     pass
    5 class SubClass1(ParentClass1):
    6     pass
    7 class SubClass2(ParentClass1,ParentClass2):
    8     pass

    如何查看继承的父类

    1 print(SubClass1.__bases__) #(<class '__main__.ParentClass1'>,)
    2 print(SubClass2.__bases__) #(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

      类的种类

     1 #Python2中分为新式类和经典类
     2 #新式类(有括号的,有继承关系的) 
     3 class Foo(object):
     4     pass
     5 #经典类(没括号的,谁都不继承)
     6 class Bar:
     7     pass
     8 #Python3中全部都是经典类(即使没有括号也是新式类)
     9 class Foo:
    10     pass
    11 print(Foo.__bases__) #(<class 'object'>,)

    继承的好处:
      1.减少冗余代码
      2.在子类定义新的属性,覆盖掉父类的属性,称为派生

     1 class Animal:
     2     def __init__(self,name,age,sex):
     3         self.name = name
     4         self.age = age
     5         self.sex =sex
     6     def eat(self):
     7         print('eating...')
     8     def talk(self):
     9         print('%s saying...' % self.name)
    10 class People(Animal):
    11     def __init__(self,name,age,sex,edu):
    12         Animal.__init__(self,name,age,sex)
    13         self.edu = edu
    14     def talk(self):
    15         Animal.talk(self)
    16         print('%s say hello' % self.name)
    17 class Pig(Animal):
    18     pass
    19 class Dog(Animal):
    20     pass
    21 p1 = People('p1',18,'male','college')
    22 g1 = Pig('g1',11,'female')
    23 d1 = Dog('d1',22,'male')
    24 print(p1.edu)
    25 p1.talk()
    26 g1.talk()
    27 d1.talk()
    28 print(isinstance(p1,People))
    29 print(isinstance(g1,Pig))
    30 print(isinstance(d1,Dog))

      对象如果要调用方法,先从对象自己的命名空间找,然后是自己的类,最后是父类,依次往上找

     1 class Parent:
     2     def foo(self):
     3         print('Parent.foo')
     4         self.bar()
     5     def bar(self):
     6         print('Parent.bar')
     7 class Sub(Parent):
     8     def bar(self):
     9         print('Sub.bar')
    10 s=Sub()
    11 s.foo() # Parent.foo
    12         # Sub.bar

    继承反应的是一种什么是什么的关系
    组合也可以解决代码冗余的问题,但是组合反应的是一种什么有什么的关系

     1 class People:
     2     def __init__(self,name,age,sex):
     3         self.name=name
     4         self.age=age
     5         self.sex=sex
     6 class Date:
     7     def __init__(self,y,m,d):
     8         self.y = y
     9         self.m = m
    10         self.d = d
    11     def tell(self):
    12         print('%s-%s-%s' % (self.y,self.m,self.d))
    13 class Teacher(People):
    14     def __init__(self,name,age,sex,salary,y,m,d):
    15         People.__init__(self,name,age,sex)
    16         self.salary = salary
    17         self.birth = Date(y,m,d)
    18 
    19 class Student(People):
    20     def __init__(self,name,age,sex,y,m,d):
    21         People.__init__(self,name,age,sex)
    22         self.birth = Date(y,m,d)
    23 
    24 t1 = Teacher('A',18,'male',3000,2000,1,1)
    25 t1.birth.tell()

    抽象类

     1 import abc
     2 class File(metaclass=abc.ABCMeta):
     3     @abc.abstractmethod
     4     def read(self):
     5         pass
     6     @abc.abstractmethod
     7     def write(self):
     8         pass
     9 class Txt(File):
    10     def read(self):
    11         pass
    12     def write(self):
    13         pass
    14 p=Txt()

    继承搜索顺序:
    Python2中,分为
    广度优先(新式类)F->D->B->A->E->C->H
    深度优先(经典类)F->D->B->E->C->H->A
    Python3中,只有广度优先(python3中只有新式类)

     1 class A:
     2     def test(self): print('from A')
     3     pass
     4 class B(A):
     5     def test(self): print('from B')
     6     pass
     7 class C(A):
     8     def test(self): print('from C')
     9     pass
    10 class D(B):
    11     def test(self): print('from D')
    12     pass
    13 class E(C):
    14     def test(self): print('from E')
    15     pass
    16 class H(A):
    17     def test(self): print('from H')
    18     pass
    19 class F(D,E,H):
    20     def test(self): print('from F')
    21     pass
    22 f=F()
    23 f.test()
    24 print(F.mro())
    25 #[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>,
    26 # <class '__main__.C'>, <class '__main__.H'>, <class '__main__.A'>, <class 'object'>]

    子类中重用父类的方法(super)

     1 class Foo:
     2     def test(self):
     3         print('from foo.test')
     4 class Bar(Foo):
     5     def test(self):
     6         super().test()
     7         print('from bar.test')
     8 b = Bar()
     9 b.test()
    10 
    11 class Foo1:
    12     def test(self):
    13         print('from foo1.test')
    14 class Foo2:
    15     def test(self):
    16         print('from foo2.test')
    17 class Bar(Foo1,Foo2):
    18     def test(self):
    19         super().test()
    20         print('from bar.test')
    21 b = Bar()
    22 b.test() #from foo1.test
    23          #from bar.test

    多态与多态性

    没有多态就没有多态性
    多态:同一种事物的多种形态
    多态性:指的是具有不同功能的函数可以使用相同的函数名

     1 class Animal:
     2     def eat(self):
     3         print('eating...')
     4 class People(Animal):
     5     def eat(self):
     6         print('eating...')
     7 class Pig(Animal):
     8     def eat(self):
     9         print('eating...')
    10 class Dog(Animal):
    11     def eat(self):
    12         print('eating...')
    13 p1=People()
    14 g1=Pig()
    15 d1=Dog()
    16 def func(obj):
    17     obj.eat()
    18 func(p1)
    19 func(g1)
    20 func(d1)

    封装

    为什么要封装:保护隐私,隔离复杂度
    Python没有真正的隐藏,只是从语法级别做了些改变

     1 class Foo:
     2     __x = 1 # '_Foo__x': 1
     3     def __test(self): # '_Foo__test': <function Foo.__test at 0x00665D68>
     4         print('from test')
     5 print(Foo.__dict__)
     6 print(Foo._Foo__x)
     7 print(Foo._Foo__test)
     8 
     9 class People:
    10     __country = 'Chinese'
    11     def __init__(self,name,age,sex):
    12         self.__name=name #只在定义阶段才会发生变形,实例产生后新加入的变量就不会变形了
    13         self.__age=age
    14         self.__sex=age
    15     def tell_info(self):
    16         print('%s:%s:%s' % (self.__name,self.__age,self.__sex))
    17 p=People('alex',18,'male')
    18 print(p.__dict__) #{'_People__age': 18, '_People__sex': 18, '_People__name': 'alex'}
    19 p.tell_info()
    20 p.__salary = 3000
    21 print(p.__dict__) #{'_People__name': 'alex', '_People__sex': 18, '_People__age': 18, '__salary': 3000}
    22 
    23 class People:
    24     __country = 'Chinese'
    25     def __init__(self,name,age):
    26         self.__name=name
    27         self.__age=age
    28     def tell_info(self):
    29         print('Name:%s,Age:%d' % (self.__name,self.__age))
    30     def set_info(self,x,y):
    31         if not isinstance(x,str):
    32             raise TypeError('must be str!!!')
    33         if not isinstance(y,int):
    34             raise TypeError('must be int!!!')
    35         self.__name = x
    36         self.__age = y
    37 p1 = People('Albert',18)
    38 p1.tell_info() # Name:Albert,Age:18
    39 p1.set_info('Baker',22)
    40 p1.tell_info() # Name:Baker,Age:22

    关于property的应用

     1 应用1:
     2 class Foo:
     3     @property
     4     def test(self):
     5         print('from foo')
     6     # test = property(test)
     7 f=Foo()
     8 # f.test() #from foo
     9 f.test #from foo
    10 
    11 应用2:
    12 class People:
    13     def __init__(self,name,weight,height):
    14         self.name = name
    15         self.weight = weight
    16         self.height = height
    17     @property
    18     def bmi(self):
    19         return self.weight / (self.height ** 2)
    20 p = People('Albert',75,1.80)
    21 p.height=1.82
    22 print(p.bmi)
    23 
    24 应用3:
    25 import math
    26 class Circle:
    27     def __init__(self,radius):
    28         self.raduis = radius
    29     @property
    30     def zc(self):
    31         return 2 * math.pi * self.raduis
    32 c = Circle(5)
    33 print(c.zc)
    34 
    35 应用4:
    36 class Person:
    37     def __init__(self,name,permission=False):
    38         self.__name = name
    39         self.permission = permission
    40     @property
    41     def name(self):
    42         return self.__name
    43     @name.setter
    44     def name(self,value):
    45         if not isinstance(value,str):
    46             raise TypeError('must be str')
    47         self.__name = value
    48     @name.deleter
    49     def name(self):
    50         if not self.permission:
    51             raise PermissionError('not allowed')
    52         del self.__name
    53 p=Person('Albert')
    54 print(p.name)
    55 p.name='Baker'
    56 print(p.name)
    57 p.permission = True
    58 del p.name

    绑定

    类中定义的函数分成两大类:
    1.绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入)
      1.绑定到类的方法:用classmethod装饰器装饰的方法。
        为类量身定制
        类.bound_method(),自动将类当作第一个参数传入(其实对象也可调用,但仍将类当作第一个参数传入)
      2.绑定到对象的方法:没有被任何装饰器装饰的方法。
        为对象量身定制
        对象.bound_method(),自动将对象当作第一个参数传入(属于类的函数,类可以调用,但是必须按照函数的规则来,没有自动传值的说法)

    2.非绑定方法:用staticmethod装饰器装饰的方法
      不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说,就是一个普通工具而已

     1 #绑定到类的方法
     2 class Foo:
     3     @classmethod
     4     def test(cls):
     5         print(cls)
     6 Foo.test() #<class '__main__.Foo'>
     7 #跟谁都不绑定的方法
     8 class Foo:
     9     @staticmethod
    10     def test(x,y):
    11         print('test',x,y)
    12 Foo.test(1,3)
    13 f=Foo()
    14 f.test(2,4)

    示例

     1 #setting文件配置
     2 # HOST = '127.0.0.1'
     3 # PORT = 3306
     4 import setting
     5 import hashlib
     6 import time
     7 class MySQL:
     8     def __init__(self,host,port):
     9         self.sql_id = self.sql_id()
    10         self.host = host
    11         self.port = port
    12         print('connecting...')
    13     @classmethod
    14     def from_conf(cls):
    15         return cls(setting.HOST,setting.PORT) #相当于MySQL(host,port)
    16     @staticmethod
    17     def sql_id():
    18         m = hashlib.md5(str(time.clock()).encode('utf-8'))
    19         return m.hexdigest()
    20     def select(self):
    21         print(self) #<__main__.MySQL object at 0x0060E2D0>
    22         print('select func',self.host,self.port)
    23 
    24 conn1 = MySQL('192.168.1.1',3306)
    25 conn1.select()
    26 print(conn1.sql_id)
    27 conn2 = MySQL.from_conf()
    28 print(conn2.sql_id)

    staticmeth与classmethod的区别

     1 class Person:
     2     def __init__(self,name,age):
     3         self.name = name
     4         self.age = age
     5     def __str__(self):
     6         print('run __str__')
     7         return 'name:%s age:%s' % (self.name, self.age)
     8 p = Person('Albert',19)
     9 print(p)
    10 
    11 #setting文件配置
    12 # HOST = '127.0.0.1'
    13 # PORT = 3306
    14 import setting
    15 class MySQL:
    16     def __init__(self,host,port):
    17         self.host = host
    18         self.port = port
    19         print('connecting...')
    20     @classmethod
    21     def from_conf(cls):
    22         return cls(setting.HOST, setting.PORT)
    23     def __str__(self):
    24         return 'from MySQL'
    25 class Mariadb(MySQL):
    26     def __str__(self):
    27         print(self.host,self.port)
    28         return 'from Maria'
    29 conn1 = Mariadb.from_conf()
    30 print(conn1)

    反射(自省)

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问,检测和修改它本身状态或行为的一种能力。
    Python面向对象中的反射:通过字符串的形式操作对象相关的属性。Python中的一切皆对象(都可以使用反射)

     1 class People:
     2     country = 'China'
     3     def __init__(self,name,age):
     4         self.name=name
     5         self.age=age
     6 print(People.country)
     7 p = People('Albert',18)
     8 print(p)
     9 print(hasattr(p,'name')) # True
    10 print(hasattr(People,'country')) #True
    11 setattr(p,'sex','male')
    12 print(p.__dict__) # {'age': 18, 'name': 'Albert', 'sex': 'male'}
    13 print(getattr(p,'nam','not exist')) # not exist
    14 print(getattr(p,'name'))
    15 # setattr(p,'x',1)
    16 if hasattr(p,'x'):
    17     res = getattr(p,'x')
    18     print(res)
    19 delattr(p,'sex')
    20 print(p.__dict__)

    练习

     1 import sys
     2 res = sys.modules[__name__] #获取当前模块 <module '__main__' from 'C:/Users/ajiax/PycharmProjects/Python17/Day07/ALesson07.py'>
     3 print(res)
     4 if hasattr(res,'People'):
     5     get = getattr(res,'People')
     6     print(get)
     7     obj=get('Baker',22)
     8 print(obj.name)
     9 
    10 
    11 class FTPClient:
    12     def __init__(self,host):
    13         self.host=host
    14         print('connecting...%s' % self.host)
    15     def interactive(self):
    16         while True:
    17             cmd_line = input('>>>:').strip()
    18             cmd_list = cmd_line.split()
    19             if hasattr(self,cmd_list[0]):
    20                 func = getattr(self,cmd_list[0])
    21                 func(cmd_list)
    22     def get(self,args):
    23         print('downloading...%s' % args[1])
    24 p = FTPClient('127.0.0.1')
    25 p.interactive()
  • 相关阅读:
    STM32 Timer : Base Timer, Input Capture, PWM, Output Compare
    Bus Blaster v4 design overview
    JTAG Communications model
    ARM JTAG 信号 RTCK 应该如何处理?
    HappyJTAG2
    用SWD调试接口测量代码运行时间 ( SWO )
    ARM Cortex Design Considerations for Debug
    Technical Information ARM-related JTAG / SWD / SWV / ETM Target Interfaces
    Keil debugging techniques and alternative printf (SWO function)
    Serial Wire Viewer (SWV)
  • 原文地址:https://www.cnblogs.com/paodanke/p/6999876.html
Copyright © 2011-2022 走看看