zoukankan      html  css  js  c++  java
  • 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"))
     
  • 相关阅读:
    Openstack API 开发 快速入门
    virtualBox虚拟机到vmware虚拟机转换
    使用Blogilo 发布博客到cnblogs
    Openstack Troubleshooting
    hdoj 1051 Wooden Sticks(上升子序列个数问题)
    sdut 2430 pillars (dp)
    hdoj 1058 Humble Numbers(dp)
    uva 10815 Andy's First Dictionary(快排、字符串)
    sdut 2317 Homogeneous squares
    hdoj 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列+二分)
  • 原文地址:https://www.cnblogs.com/wenm1128/p/11698769.html
Copyright © 2011-2022 走看看