• python学习笔记之--面向对象技术


    类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

    方法:类中定义的函数。
    类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
    数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
    方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
    局部变量:定义在方法中的变量,只作用于当前实例的类。
    实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
    继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
    实例化:创建一个类的实例,类的具体对象。
    对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

    类:①属性(类变量和实例变量)

           ②方法(实例方法、类方法和静态方法)


    类的定义

    使用class语句来创建一个新类,class之后为类的名称,类名后有一括号,括号中为基类(可以有多个基类)然后以冒号结尾

    类比说明:
    生产杯子,杯子的模具(类),可以设定不同的参数来生产杯子。
    设定好不同的参数(通过构造函数传参)
    生产出具体的杯子(实例化)

    #用class关键字来定义一个类
    class Person:
        """文档字符串"""
    
        def __init__(self,name,age):
            if isinstance(age,int) and age >0:
                self.age = age
            else:
                self.age = 0
            self.name = name
            
    
        def set_age(self,age):
            if isinstance(age,int) and age >0:
                self.age = age
    
    
        def get_age(self):
            return self.age
    
    
    p1=Person("wulaoshi",18)
    p2=Person("lilaoshi",28)

    类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。


     各种名词的实例示意

    class Person:
        count = 0  #类变量
        nation = "中国"
    
        def __init__(self,name,gender):    #构造函数:只在实例化的时候才会调用
            self.name = name      #实例变量
            self.gender = gender
            Person.count +=1
    
        def get_name(self):   #实例方法,必须要实例化
            return self.name
    
        #类方法
        @classmethod
        def get_instance_count(cls):
            return Person.count
    
        @classmethod
        def create_a_instance(cls):
            return Person("","")
    
        @staticmethod   #静态方法
        def get_nation():
            return Person.nation
    
    wulaoshi = Person("吴老师","Male")  #实例化:类名+(参数)
    lilaoshi = Person("李老师","Female")
    总结:
    类变量:count
    实例变量:self.name
    实例化:wuloashi=Person("吴老师","Male")
    实例对象:wulaoshi
    实例方法:get_name
    类方法:get_instance_count
    静态方法:get_nation
     

     实例化

    #不需要写构造函数也可以做实例化
    class P:
        pass
     
    p=P() #这就是一个简单的实例化
     
    #写构造函数的实例化例子:
      思考:既然可以不写构造函数来做实例化,那为什么还要写构造函数来做实例化呢?
          答:当你需要传一些参数来生成实例的时候就需要构造函数来实现了(比如生成一个杯子的模具,需要长宽高能参数)
    class Person:
        def __init__(self,name):
            self.name = name
     
    p=Person("老王") #需要传参
    print(p.name)

     类变量

    #类变量:类变量紧接在类名后面定义,所有的实例都可以访问,可以理解为全局变量;放在方法的外面
    '''
    类内存:
    存类的方法
    类变量
    '''
    为什么要存在类变量?类变量可以用在什么地方?
    场景:我想记录一下总共生成了多少个实例?这个时候就可以用类变量
    class Person:
        x=0  #类变量
    
        def __init__(self,name):
            self.name = name
            Person.x+=1  #类名.类变量 来访问类
    
        def get_name(self):
            print(self.name)
    
    p1=Person("wulaoshi")
    p2=Person("laoli")
    p3=Person("laoli")
    
    print(Person.x)
    print(p1.x)
    print(p2.x)

     运行结果:

    E:>py -3 a.py
    3
    3
    3


     实例变量

     通俗来讲,在类里定义的前面加self.xxxx的变量就是实例变量。

    思考:类变量和实例变量的区别?

        答:类变量定义在类里的函数体之外,只有一份全局生效;实例变量只在方法体内部生效,在同一个类里面可以夸方法访问,可以有0个、1个或多个。

    class Person:
    
    
        def __init__(self,name,gender,age):
            self.name = name      #实例变量
            self.gender = gender  #实例变量
            age = age  #局部变量
    
        def get_name(self):   #实例方法,必须要实例化
            return self.name
    
        def get_age(self):
            return self.age
    
    xiaoli = Person("小李","Male",18)
    
    print(xiaoli.get_name())   #用实例对象来调用实例方法
    print(Person("小李","Male",18).get_nam())   #用实例来调用实例方法
    
    print(xiaoli.get_age())   #局部变量不能夸方法访问

    E:>py -3 a.py
    小李
    小李
    Traceback (most recent call last):
    File "a.py", line 20, in <module>
    print(xiaoli.get_age())
    File "a.py", line 13, in get_age
    return self.age
    AttributeError: 'Person' object has no attribute 'age'


     构造函数 

     __inint__是python的内置方法,该方法在类实例化时会自动调用

    class Person:
    
        def __init__(self,name):   #构造方法,用来初始化的,也可以不传参数
            self.name = name
    
    p = Person("xz")   #类的实例化操作会自动调用 __init__() 方法
    
    print(p.name)

    E:>py -3 a.py
    xz


     self的含义

    self代表类的实例,而非类。

    self传递的是某个实例的地址。实例地址里面的所有变量都可以在方法中进行使用。

    class P:
    
    
        def __init__(self,value): 
            self.value = value
            
        def get(self):  #实例方法
            return "***:"+str(self.value)
    
    
        def set(self,value):  #实例方法
            if isinstance(value,(int,float)):
                self.value = value
            return None
    
    
    p1 =P(1)
    p2 =P(2)
    p3 =P(3)
    
    '''
    内存中的位置:A
    P:类变量
    类定义的方法
    
    内存中的位置:b
    p1的实例:self.value=1
    
    内存中的位置:c
    p2的实例:self.value=2
    
    内存中的位置:d
    p3的实例:self.value=3
    '''
    
    #调用过程解析:
    '''
    p1.get()--->会把内存位置b发送给类定义的方法P.get
    self:是一个方法的参数,指向内存位置b。
    get方法会从内存b的位置找到,value值,然后执行方法中的代码。
    
    '''

     总结:

    类中的实例方法中的第一个参数self,实际上就是
    实例所在内存的地址,通过这个地址,可以找到
    实例方法中需要使用的各种实例属性(数据)

     私有变量

     什么情况需要使用私有变量?

    下面来看一个场景示例:

    class Person:
    
    
        def __init__(self,name,age):
            if isinstance(age,int) and age >0:
                self.age = age
            else:
                self.age = 0
            self.name = name
            
    
        def set_age(self,age):
            if isinstance(age,int) and age >0:
                self.age = age
    
    
        def get_age(self):
            return self.age
    
    
    p1=Person("wulaoshi",18)
    p2=Person("lilaoshi",28)
    p1.age=-1     #虽然制定了一些规则(方法)来保证数据的安全性,但是如果绕过方法直接给变量赋一个值,还是可以把它改成不合法的数据;这个时候就需要用私有变量来限制外部对变量的操作
    print(p1.age)
    D:>py -3 a.py
    -1
     
    #虽然制定了一些规则(方法)来保证数据的安全性,但是如果绕过方法直接给变量赋一个值,还是可以把它改成不合法的数据;这个时候就需要用私有变量来限制外部对变量的操作
    #私有变量:前面加下划线
    class Person:
    
        def __init__(self,name,age):
            if isinstance(age,int) and age >0:
                self.__age = age
            else:
                self.__age = 0
            self.name = name  #为什么要写一下self.name=name,self.name叫实例变量,name叫局部变量,如果不写self.name=name在类的其他方法里就不能在使用name这个变量
            
    
        def set_age(self,age):
            if isinstance(age,int) and age >0:
                self.__age = age
    
        def get_age(self):
            return self.__age
    
    p1=Person("wulaoshi",18)
    p2=Person("lilaoshi",28)
    #print(p1.__age)   #这里如果外部访问私有变量会报错:AttributeError: 'Person' object has no attribute '__age'
    p1.__age=100 #这里被认知直接给__age赋值,不是方法里实例变量的值
    print(p1.__age) #打印100
    print(p1.get_age()) #打印18
    C:UsersdellDesktop练习6>py -3 0614.py
    100
    18

    方法

     操作属性的动作叫方法

    方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
    ➢普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
    ➢类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
    ➢静态方法:由类调用;无默认参数

    #encoding=utf-8
    class Foo:
    
    
        def __init__(self, name):
            self.name = name
    
        #实例方法
        def ord_func(self):
            """ 定义普通方法,至少有一个self参数 """
    
    
            # print self.name
            print ('普通方法')
    
        #类方法
        @classmethod
        def class_func(cls):
            """ 定义类方法,至少有一个cls参数 """
    
    
            print ('类方法')
    
    
    #静态方法 @staticmethod
    def static_func(): """ 定义静态方法 ,无默认参数""" print ('静态方法') f=Foo("吴老师")
    #调用实例方法 f.ord_func()
    #调用类方法 Foo.class_func() f.class_func()
    #调用静态方法 Foo.static_func() f.static_func()

     私有方法

     类中方法名前面有两个下划线,表示是Python中的私有方法,不能在类外部调用(如__setId()),在类内部调用语法: self.__private_methods。

    #coding=utf-8
    class Person(object):
        id = 12 #类静态成员在这儿定义,注意缩进
        def __init__(self,name):
            self.name = name
            self.__inName = 'ads'
    
        def __setId(self,id): #隐藏方法
            Person.id = id * 2
    
        def getId(self):
            self.__setId(18) #类内部调用隐藏方法
            return Person.id
    
    p = Person("prel")
    print (p.getId())
    print ("类外部调用私有方法")
    print (p.__setId(10))

    使用函数添加、删除、修改、访问类属性

    可以使用以下函数来操作对象的属性:
    1、getattr(obj, name[, default]) : 访问对象的属性,如果存在返回对象属性的值,否则抛出AttributeError异常。
    2、hasattr(obj,name) : 检查是否存在某个属性,存在返回True,否则返回False。
    3、setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性,该函数无返回值。若存在则更新这个值
    4、delattr(obj, name) : 删除属性,如果属性不存在则抛出AttributeError异常,该函数也无返回值。

    class Person:
        count =0 #类变量
        def __init__(self,name): #构造方法
            self.name =name
            Person.count+=1
    
    
        def get_name(self):
            return self.name
    
    
    print(getattr(p,"name"))
    print(p.name)
    print(getattr(p,"name","name not exist!"))
    setattr(p,"name","李老师")
    print(getattr(p,"name"))
    print(hasattr(p,"name1"))
    print(delattr(p,"name"))
     
  • 相关阅读:
    Delphi实战中讲解FormCreate,FormShow,FormActivate
    delphi Try except on e:Exception do
    Delphi处理数据网格DBGrid的编辑框 获取还没有提交到数据集的字段文本
    delphi dbgrid中如何自动生成序号
    DBDateTimePicker;
    Delphi控件开发浅入深出(八)
    delphi中日期类型TDateTime使用总结
    在DBGrid录数据时,如何判断光标位置是在数据的最左或最右,如果是最左或最右则在按左右光标键时光标跳到上一格或下一格,如果是在数据中
    请问如何按Enter键让DBGrid的光标向右移以及换行?(0分)
    tdbgrid中用enter仿真tab键盘_delphi教程
  • 原文地址:https://www.cnblogs.com/wenm1128/p/11698769.html
Copyright © 2020-2023  润新知