zoukankan      html  css  js  c++  java
  • Python基础知识之面向对象编程

    1. 实例变量与类变量

    class Role:
        n = 123  # 类变量
        n_list = []
        name = "我是类name"
    
        def __init__(self, name, role, weapon, life_value=100, money=15000):
            # 构造函数
            # 在实例化时做一些类的初始化的工作
            # self就相当于一个实例化的对象
            self.name = name  # r1.name=name实例变量(静态属性),作用域就是实例本身
            self.role = role
            self.weapon = weapon
            self.life_value = life_value
            self.money = money
    
        def __shot(self):  # 类的方法,功能 (动态属性)
            print("shooting...")
    
    
    r1 = Role('Chenronghua', 'police', 'AK47')  # Role(r1,'Alex', 'police',  'AK47')把一个类变成一个具体对象的过程叫 实例化(初始化一个类,造了一个对象)
    r1.n = 456
    print(r1.n)  # 456  并没有改变类变量n。而是在对象r1中自动生成了一个实例变量n
    print(Role.n)  # 123
    
    r2 = Role('jack', 'terrorist', 'B22')  # 生成一个角色
    r2.n_list.append("from r1")
    print(r2.n_list,Role.n_list) # ['from r1'] ['from r1']  直接修改了类的类变量 n_list
    r2.bullet_prove = True  # 这句话是对的,相当于定义了一个对象r2之后,新增了一个实例变量bulet_prove
    del r2.weapon # 删除实例变量weapon
    
    
    

    类变量的作用:大家共用的属性,节省开销

    2. 析构函数

    在实例释放、销毁的时候执行的,通常用来做一些收尾工作,如关闭一些数据库链接,打开的临时文件。

    def __del__(self):
    	print("%s 彻底销毁了。。。",self.name)
    

    3. 私有属性

    私有属性在类的内部可以访问,在类的外部无法访问在构造函数中定义,在前面加上__就可以了。

    定义如下:

        def __init__(self, name, role, weapon, life_value=100, money=15000):
            self.name = name  # r1.name=name实例变量(静态属性),作用域就是实例本身
            self.role = role
            self.weapon = weapon
            self.__life_value = life_value # 这里的life_value就是一个私有属性了。
            self.money = money
    

    那么如何访问私有属性呢?这个时候需要在类的内部定义方法来实现:

        def get_lifevalue(self):
            print(self.__life_value)
    

    4. 私有方法

    私有方法在类的内部可以访问,在类的外部无法访问。在类内定义私有方法只需要在方法名前面加上__就可以了。

    定义如下:

    def __fun1(self):
    	print("这是一个私有方法!")
    

    5. 类的继承

    class Parent(object):
      	__init__(self):
        	pass
     class Child(Parent):
        pass
    

    6. 类方法的重构

    # class People: 经典类
    class People(object):  # 新式类
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    
    class Man(People):
        # 重构父类方法
        def __init__(self, name, age, money):
            People.__init__(self, name, age)  # 经典类的写法
            super(Man, self).__init__(name, age)  # 新式类的写法
            self.money = money
           
    

    7. 新式类和经典类的区别

    在Python2.7中

    BC为A的子类,D为BC的子类,A中有save方法,C对其进行了重写

    • 在经典类中 调用D的save方法 搜索按深度优先 路径B-A-C, 执行的为A中save 显然不合理
    • 在新式类的 调用D的save方法 搜索按广度优先 路径B-C-A, 执行的为C中save
    #经典类
    class A:
        def __init__(self):
            print 'this is A'
    
        def save(self):
            print 'come from A'
    
    class B(A):
        def __init__(self):
            print 'this is B'
    
    class C(A):
        def __init__(self):
            print 'this is C'
        def save(self):
            print 'come from C'
    
    class D(B,C):
        def __init__(self):
            print 'this is D'
    
    d1=D()
    d1.save()  #结果为'come from A
    
    #新式类
    class A(object):
        def __init__(self):
            print 'this is A'
    
        def save(self):
            print 'come from A'
    
    class B(A):
        def __init__(self):
            print 'this is B'
    
    class C(A):
        def __init__(self):
            print 'this is C'
        def save(self):
            print 'come from C'
    
    class D(B,C):
        def __init__(self):
            print 'this is D'
    
    d1=D()
    d1.save()   #结果为'come from C'
    

    在Python 3.x中,经典类和新式类均为广度优先

    8. 多态

    一种接口,多种实现。

    #_*_coding:utf-8_*_
     
     
    class Animal(object):
        def __init__(self, name):  # Constructor of the class
            self.name = name
     
        def talk(self):              # Abstract method, defined by convention only
            raise NotImplementedError("Subclass must implement abstract method")
     
     
    class Cat(Animal):
        def talk(self):
            print('%s: 喵喵喵!' %self.name)
     
     
    class Dog(Animal):
        def talk(self):
            print('%s: 汪!汪!汪!' %self.name)
     
     
     
    def func(obj): #一个接口,多种形态
        obj.talk()
     
    c1 = Cat('小晴')
    d1 = Dog('李磊')
     
    func(c1)
    func(d1)
    

    9. 静态方法

    静态方法定义在类中,名义上归类管,相当于类的工具包。

    class Dog(object):
        @staticmethod #静态方法装饰器,实际上和类没有什么关系
        def eat():
            print("You are eating some food!")
    
    
    d = Dog()
    d.eat()  # 可以通过实例化对象调用静态方法
    Dog.eat() # 直接通过类名调用静态方法
    

    10. 类方法

    类方法只能访问类变量,不能访问实例变量

    class Dog(object):
        name = "Jack"
    
        @classmethod  # 类方法装饰器
        def eat(cls): # 这里不是self 而是cls
            print("%s is eating!"%cls.name)
    d = Dog()
    d.eat()
    Dog.eat()
    
    

    11.属性方法

    属性方法就是把一个方法变成一个静态属性。

    class Dog(object):
        name = "Jack"
    
        @property  # 注意不是attribute
        def eat(self):
            print("%s is eating!" % self.name)
    
    
    d = Dog()
    # d.eat()  # 会报错:TypeError: 'NoneType' object is not callable
    d.eat  # Jack is eating!
    # Dog.eat()  #
    

    调用的时候不能加括号

    那么,既然是一个静态属性,那么就意味着我们无法对其传参,只能读取。

    考虑一下,首先,如果我们在类内直接赋予参数,应该如何呢?

    class Dog(object):
        name = "Jack"
    
        @property  # 注意不是attribute
        def eat(self, food):
            print("%s is eating!" % self.name)
    
    
    d = Dog()
    d.eat("baozi")  # TypeError: eat() missing 1 required positional argument: 'food'
    # 如果给他赋值呢?
    # d.eat = "baozi"  # AttributeError: can't set attributeQ
    
    

    从上面的代码我们可以看出,属性方法我们无法直接对其进行赋值,这个时候就需要使用如下方法:

    class Dog(object):
        name = "Jack"
    
        def __init__(self):
            self.__food = None
    
        @property  # 注意不是attribute
        def eat(self):
            print("%s is eating! %s" % (self.name, self.__food))
    
        #需要定义在eat之后
        @eat.setter
        def eat(self,food):
            self.__food = food
            print("set to food:%s" %food)
    
    d = Dog()
    d.eat = "baozi"
    d.eat
    
    

    那么如何删除属性方法呢?

    del d.eat
    >>>  File "D:/Python/PycharmProjects/test/core/main.py", line 24, in <module>
        del d.eat
    AttributeError: can't delete attribute
    

    显然,直接删除是不正确的,这个时候,就需要重新定义:

        @eat.deleter
        def eat(self):
            del self.__food
            print("删完了")
    

    再使用:

    del d.eat
    

    来删除属性。

    好吧,把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

    1. 连接航空公司API查询
    2. 对查询结果进行解析
    3. 返回结果给你的用户

    因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?

    class Flight(object):
        def __init__(self,name):
            self.flight_name = name
    
    
        def checking_status(self):
            print("checking flight %s status " % self.flight_name)
            return  1
    
        @property
        def flight_status(self):
            status = self.checking_status()
            if status == 0 :
                print("flight got canceled...")
            elif status == 1 :
                print("flight is arrived...")
            elif status == 2:
                print("flight has departured already...")
            else:
                print("cannot confirm the flight status...,please check later")
    
    
    f = Flight("CA980")
    f.flight_status
    
    航班查询
    
  • 相关阅读:
    搭建SSM框架 Demo
    Mybatis (ParameterType) 如何传递多个不同类型的参数
    IDEA如何将本地项目上传到码云
    VUE项目
    Oralce(三)特殊符号
    NodeJS and Intellij IDEA
    Handler
    Netty 框架 (一) channelDisconnected、channelClosed两个事件区别
    数据库索引
    Websocket
  • 原文地址:https://www.cnblogs.com/bearkchan/p/8242902.html
Copyright © 2011-2022 走看看