• 面向对象


    类的语法:

    class Animal(object):  #class是创建类的关键字  Animal是类名  object是新式类的写法
        def __init__(self,name): #初始化方法,也称构造方法,创建了类的实例时会调用该方法, self代表实例本身,谁调用类,self就是谁。name是属性,也成实例变量
            self.name = name   
        def talk(self):    #self在定义类的方法时必须有,虽然调用时不必传入参数
            print('animal [%s] is talking'%self.name)
    a1 = Animal('dog')   #类的实例化 ,python会自动把a1变量赋值给self这个参数
    a1.talk()
    #1,实例化时会在内存里开辟一块空间指向 a1这个变量名
    #2,调用Animal类并执行__init__(...)为了把name等属性跟刚开辟的a1关联起来,关联后就可以直接用a1.name 调用了
    #3,所以这个__init__(…)方法里的,self.name = name,self.role = role的意思就是要把这几个值存到a1的内存空间里

    类的实例化:把一个抽象的类通过实例化变为一个具体的对象

    面向对象编程三个特点:封装,继承,多态

    封装:把使用构造方法将内容封装到某个具体对象中,然后通过对象直接或者self间接获取被封装内容。

    继承:在OOP程序设计中,定义一个class的时候,可以从某个现有的class继承,通过继承创建的新的class 称为 子类 或 派生类 ,被继承的class称为 基类、父类 或 超类。

    例如:

    class Animal(object):
        def talk(self):
            print('animal is talking')
    class Dog(Animal):  #子类
        pass
    class Cat(Animal):   #子类
        pass
    d=Dog()
    c=Cat()
    d.talk()   #继承了父类的方法
    c.talk()   #继承了父类的方法
    得到
    animal is talking
    animal is talking

    继承的时候,如果父类和子类都有相同方法,执行哪一个呢?

    class Animal(object):
        def __init__(self):  
            self.func()
        def func(self):    
            print("Animal Class")
    class Dog(Animal):    
        def func(self):   #与父类同名的方法func()
            print("Dog class")
    d = Dog()    #实例化了子类
    结果: 
    Dog class

    对象之间的交互:

    '''
    对象之间的交互
    '''
    class Animal:
        '''奥特曼和小怪兽都有的属性,名字,伤害值,生命值'''
        def __init__(self,name,damage,life_value):
            self.name = name
            self.damage = damage
            self.life_val = life_value
    class People(Animal):
        '''人可以攻击小怪兽'''
        def attack(self,monster):
            monster.life_val -= self.damage
    class Monster(Animal):
        '''小怪兽咬人'''
        def bite(self,people):
            people.life_val -= self.damage
    p=People('奥特曼',30,2000)
    m=Monster('小怪兽',20,1000)
    print("奥特曼初始生命值",p.life_val)
    m.bite(p)
    m.bite(p)
    print("奥特曼被咬了两口:",p.life_val)
    print('--------------------------------')
    print("小怪兽初始生命值",m.life_val)
    p.attack(m)
    print("小怪兽挨揍了之后生命值",m.life_val)
    
    结果:
    奥特曼初始生命值 2000
    奥特曼被咬了两口: 1960
    --------------------------------
    小怪兽初始生命值 1000
    小怪兽挨揍了之后生命值 970
    class Monster:
        def __init__(self,name,damage,life_value):
            self.name = name
            self.damage = damage
            self.life_value = life_value
        def bite(self,person):
            '''怪兽咬人,人的生命值减少'''
            person.life_value -= self.damage
    class People:
        def __init__(self,name,money,life_value,damage = 0):
            '''人的属性:名字,生命值,钱,战斗力为0'''
            self.damage = damage
            self.name = name
            self.life_value = life_value
            self.money = money
    class Weapon:
        '''武器类:名字,价格,战斗力'''
        def __init__(self,name,value,damage):
            self.name = name
            self.value = value
            self.damage = damage
        def buyed_by(self,people):  #击中对方,对方生命值减少
            people.money -= self.value
            people.damage += self.damage
        def shooted(self,obj):    #击中对方,对方生命值,战斗力减少
            obj.life_value -= self.damage
            obj.damage -= 100
    if __name__ == "__main__":
        p = People('正义者',1000,5,0)
        m = Monster('怪兽',100,5)
        w = Weapon('AK48',200,500)
        if p.money > w.value:
            print("正义者买了一把枪")
            w.buyed_by(p)
            p.weapon = w
        else:
            print("正义者还买不起武器,只能等死了...")
        print("怪兽生命值:%s,战斗力:%s"%(m.life_value,m.damage))
        p.weapon.shooted(m)
        print("正义者开枪了")
        print("怪兽生命值:%s,战斗力:%s" % (m.life_value, m.damage))
    
    结果:
    正义者买了一把枪
    怪兽生命值:5,战斗力:100
    正义者开枪了
    怪兽生命值:-495,战斗力:0
    一个小游戏

     继承和重写

    class SchoolMember(object):   #父类
        def __init__(self,name,age):
            self.name = name
            self.age = age
    class Student(SchoolMember):   #子类
        def __init__(self,name,age,grade):   #先重写
            super(Student,self).__init__(name,age)  #后继承  super关键字
            self.grade = grade
        def prt_name(self):
            print("student [%s]'s grade is [%s]"%(self.name,self.grade))
    class Teacher(SchoolMember):   #子类
        def __init__(self,name,age,course):   #重写
            super(Teacher,self).__init__(name,age)  #继承
            self.course = course
        def Teach(self):
            print('Teacher %s is teaching [%s] now'%(self.name,self.course))
    s=Student('lily',22,14)    #类的实例化
    s.prt_name()    #调用方法
    t=Teacher('alex',30,'python')    #类的实例化
    t.Teach()

    可以通过  issubclass(sub,super) 判断是否是继承关系

    print(issubclass(Student,SchoolMember))

    多态:实现接口的重用。

    class Animal(object):
        def __init__(self,name):
            self.name = name
        def talk(self):
            print('animal [%s] is talking'%self.name)
    class Dog(Animal):
        def talk(self):     #父类里已存在talk方法。子类可以进行方法重写
            print('Dog [%s] is wow wow wow'%self.name)
    class Cat(Animal):
        def talk(self):
            print('Cat [%s] is miao miao miao'%self.name)
    def func(obj):   #一个接口 多种形态
        obj.talk()
    d=Dog('小黑')
    c=Cat('小喵')
    func(d)   #调用子类Dog的方法
    func(c)   #调用子类Cat的方法
    ---------->
    Dog [小黑] is wow wow wow
    Cat [小喵] is miao miao miao

     类变量vs实例变量

    类变量是创建类时就存在类的内存空间里面的。而实例变量是类实例化时,存在实例的内存空间里的

    class People(object):
        num = 0          #类变量
        def __init__(self,name):
            self.name = name     #实例变量,通过实例来访问
        def study(self):
            People.num += 10   #  类变量使用类来访问
            print('num[%s] student %s is studing...'%(self.num,self.name))
    p = People('lily')
    p.study()
    print(People.num)
    print(p.num)
    ----------->
    num[10] student lily is studing...
    10
    10
    #------------错误的示例---------------------
    class People(object):
        num = 0           #类变量
        def __init__(self,name):   #实例变量
            self.name = name
        def study(self):
            self.num += 10  #不能改变类变量,而是跟类变量重名的实例变量
            print('num[%s] student %s is studing...'%(self.num,self.name))
    p = People('lily')
    p.study()
    print(People.num)
    print(p.num)
    ----------------------->
    num[10] student lily is studing...
    0
    10

    静态方法  

    @staticmethod装饰器可以把一个方法变成静态方法。  静态方法不能访问实例变量和类变量,跟类没什么关联,只能通过类名来调用方法

    class People(object):
        num = 0   #类变量
        def __init__(self,name):
            self.name = name   #实例变量
        @staticmethod
        def study(self):
            print('student %s is studing...'%(self.name))  #不能访问self.num 也不能访问self.name
    p = People('lily')
    p.study()
    ------------------->
    报错:study() missing 1 required positional argument: 'self'

    除非把实例本身当做传给study方法 p.study(p)

    类方法

    @classmethod  装饰器可以把一个方法变成类方法。类方法只能访问类变量不能访问实例变量

    class People(object):
        num = 0   #类变量
        def __init__(self,name):
            self.name = name   #实例变量
        @classmethod
        def study(self):
            print('num[%s] student %s is studing...'%(self.num,self.name)) #可以访问self.num 类变量,不能访问self.name实例变量
    p = People('lily')
    p.study()
    ------------->
    报错AttributeError: type object 'People' has no attribute 'name'  

    属性方法

    @property  把一个方法变成属性

    class People(object):
        def __init__(self,name):
            self.name = name
        @property   # 把study方法变成一个属性
        def study(self):
            print('student %s is studying...'%self.name)
    p = People('lily')
    p.study    # 属性,只读 
    p.name = 'jack'   #此时外部可以调用name变量,这时可以使用__把name变成私有变量,使外部无法调用
    p.study    
    --------------->
    student lily is studying...
    student jack is studying...
    
    p.study = 'hena'  #修改的话会报错,因为study属性不可修改
    --------------->
    AttributeError: can't set attribute

    可以加上一个setter改为可写属性

    class People(object):
        def __init__(self):
            self.__name = None
        @property   # 把study方法变成一个属性
        def study(self):
            return self.__name
        @study.setter   # 把study属性变成一个可写的属性
        def study(self,value):
            self.__name = value
        @study.deleter    #删除
        def study(self):
            del self.__name
    p = People()    
    print(p.study)   
    p.study = 'lily'
    print(p.study)
    ----------------->
    None
    lily
    
    del p.study
    print(p.study)
    ---------------------->     #报错,说明p.study属性已经被删除
    AttributeError: 'People' object has no attribute '_People__name'

    类的特殊成员方法

    __str__ 和 __repr__

    #不加__str__时
    >>> class P:
    ...      def __init__(self,name,age):
    ...              self.name = name
    ...              self.age = age
    >>> a=P('lily',999)
    >>> print(a)
    <__main__.P object at 0x7f4703aac400> 
    
    #如果要把一个类的实例变成str,就需要用__str__
    >>> class P:
    ...      def __init__(self,name,age):
    ...              self.name = name
    ...              self.age = age
    ...      def __str__(self):
    ...              return 'name: %s,age: %s'%(self.name,self.age)
    ... 
    >>> b=P('xiaohei',10)
    >>> b
    <__main__.P object at 0x7f4703aac748>  
    >>> print(b)
    name: xiaohei,age: 10
    
    #__str__()用于显示给用户看,而__repr__()是显示给开发人员看
    
    >>> class P:
    ...      def __init__(self,name,age):
    ...              self.name = name
    ...              self.age = age
    ...      def __str__(self):
    ...              return 'name: %s,age: %s'%(self.name,self.age)
    ...      __repr__ = __str__
    ... 
    >>> c=P('lin',20)
    >>> c
    name: lin,age: 20
    >>> print(c)
    name: lin,age: 20
    View Code

    __doc__  类的描述信息

    class A:
        '''
        this is a test class
        '''
        def func(self):
            pass
    print(A.__doc__)
    -------------------------->
    
        this is a test class
    View Code

    __module__ 对象在哪个模块

    # python example.py
    class A:
        def func(self):
            pass
    a = A()
    print(a.__module__)
    #结果------------------->
    __main__
    
     # python test.py
    from example import A
    x = A()
    print(x.__module__)
    #结果------------------>
    example
    example
    View Code

    __class__ 对象是什么类

    # python example.py
    class A:
        def func(self):
            pass
    a = A()
    print(a.__class__)
    ----------------->
    <class '__main__.A'>
    
    
    # python  test.py
    from example import A
    x = A()
    print(x.__class__)
    -------------------->
    <class 'example.A'>
    <class 'example.A'>
    View Code

    __dict__    查看类或对象中的成员

    class A:
        def __init__(self,name):
            self.name = name
        def func(self):
            return self.name
    print("类的成员:",A.__dict__)
    a = A('lily')
    print("对象的成员:" ,a.__dict__)
    
    ----------------->
    类的成员: {'__module__': '__main__', '__init__': <function A.__init__ at 0x0000004135DFDD08>, 'func': <function A.func at 0x0000004135DFDE18>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
    对象的成员: {'name': 'lily'}
    View Code

    python的反射机制

    getattr(object,name,[value])  获取

    setattr(object, name, value)  设置

    hasattr(object, name)   判断 

    delattr(object, name)  删除

    >>> class Myclass(object):
    ...      def __init__(self,name):
    ...              self.name = name
    ...      def func(self,value):
    ...              self.value = value
    ...              print("value is: ",self.value)
    ... 
    >>> obj = Myclass("lily")
    >>> hasattr(obj,"name")  #判断obj对象是否有name属性
    True
    >>> hasattr(Myclass,"name")  #判断类是否有name属性
    False
    >>> hasattr(Myclass,"func")   #判断class是否有func方法
    True
    >>> hasattr(obj,"func")
    True
    
    >>> getattr(obj,"name")  #获取值
    'lily' 
    >>> getattr(obj,"func")    #获取obj.func方法的内存地址
    <bound method Myclass.func of <__main__.Myclass object at 0x7f78283302e8>>
    >>> x=getattr(obj,"func")  
    >>> x(22)     # 调用方法  等同于obj.func(22)
    value is:  22
    >>> 
    >>> def test_run(server): 
    ...      print("%s running..."%server)
    ... 
    >>> setattr(obj,"run",test_run)  #将test_run绑定到obj对象,命名为run
    >>> obj.run("ftp")
    ftp running...
    import sys
    class Webserver(object):
        def __init__(self,host):
            self.host = host
        def start(self):
            print("server is start...")
        def stop(self):
            print("server is stop...")
        def restart(self):
            self.start()
            self.stop()
    def test_run(self,name):
        print("%s running...%s"%(name,self.host))
    if __name__ == '__main__':
        s = Webserver('localhost')
        if hasattr(s,sys.argv[1]):   #判断是否有这个方法
            func = getattr(s,sys.argv[1])   #获取s.start方法的内存地址
            func()
        setattr(s,"run",test_run)
        s.run(s,'mysql')
        delattr(Webserver,'stop')  #只能类删除类方法,实例删不了,实例只能删除实例属性host
        s.restart()  #会报错'Webserver' object has no attribute 'stop'
    View Code
  • 相关阅读:
    一个判断浏览器类型的JS
    asp中输出xml “文本内容中发现无效字符”问题的解决(转)
    Excel VBA工程密码之最简单破解法
    爆破AspriseOCR 4.0
    vi编辑器的使用(转载)
    数据挖掘(转载)
    简单工厂模式(SimpleFactory)
    工厂方法模式(Factory Method)
    让gridview默认处于编辑模式并取得编辑后的值
    GDB调试精粹及使用实例(转载)
  • 原文地址:https://www.cnblogs.com/xiaobaozi-95/p/9546972.html
Copyright © 2020-2023  润新知