Python学习笔记8:面向对象

Python学习笔记8:面向对象[Python基础]

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

类定义

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

类变量和实例变量
通常来说,实例变量是对于每个实例都独有的数据,而类变量是该类所有实例共享的属性和方法。

class Dog:
    kind = "canine" # class variable

    walk_place = []

    def __init__(self, name):
        self.name = name # instance variable

上面类Dog中,类属性kind为所有实例所共享;实例属性name为每个Dog的实例独有。

类对象和实例对象
Python中一切皆对象;类定义完成后,会在当前作用域中定义一个以类名为名字,指向类对象的名字。实例对象是类对象实例化的产物。

class Dog:
    kind = "canine" # class variable

    walk_place = []

    def __init__(self, name):
        self.name = name # instance variable

    def walk(self, place):
        self.walk_place.append(place)

dog = Dog("James")
dog.walk("shenzhen")
print(Dog.walk_place)

上面类Dog中,Dog属于类对象,而实例化后的dog则是实例对象。

属性绑定
在定义类时,通常我们说的定义属性,其实是分为两个方面的:
a.类属性绑定
b.实例属性绑定
用绑定这个词更加确切;不管是类对象还是实例对象,属性都是依托对象而存在的。

Python作为动态语言,类对象和实例对象都可以在运行时绑定任意属性。因此,类属性的绑定发生在两个地方:
a.类定义时;
b.运行时任意阶段。

类属性绑定,因为是动态语言,所以可以在运行时增加属性,删除属性。如下代码:

class Dog:
    kind = "canine" # class variable
    def __init__(self, name):
        self.name = name # instance variable

Dog.color = "yellow"
print(Dog.kind)
print(Dog.color)
del Dog.color
print(Dog.color) #error
Exception has occurred: AttributeError
type object "Dog" has no attribute "color"
  File "D:zPY	est	est_class.py", line 21, in <module>
    print(Dog.color)

实例属性绑定,就是类实例化后再绑定属性。
因为__init__(构造方法)在实例化时执行,所以self.name = name也是属于实例属性绑定。
如下代码:

class Dog:
    kind = "canine" # class variable
    def __init__(self, name):
        self.name = name # instance variable

dog = Dog("James")
dog.color = "yellow"
print(dog.name)
print(dog.color)

self
self代表类的实例,而非类,是当前对象的地址。
self 不是 python 关键字,我们把他换成其他字符也是可以正常执行的。
还有另外一个问题,定义属性或者方法时,哪些需要加self哪些不需要呢?

私有方法,类方法,静态方法
私有方法:以 __两个下划线开头,声明该方法为私有方法,只能在类的内部调用 (类内部别的方法可以调用他),不能在类地外部调用。
类方法:在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
静态方法:需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数

class People(object):
    country = "china"

    #私有方法
    def __private_meth(self):
        print("this is a private method")

    #类方法
    def class_meth(self):
        print("this is a class method")

    #静态方法,不用定义参数
    @staticmethod
    def getCountry():
        return People.country

私有属性与私有方法

# 私有属性
__private_attrs # 不能在类的外部被使用,在内部可以正常调用self.__private_attrs
# 私有方法
__private_methods # 与私有属性类似,不能在类的外部调用,但是内部正常使用self.__private_methods

双下划线、单下划线、头尾双下划线

__name__ # 特殊方法,一般是系统定义名字
__private # 私有类型,只有类对象可以访问,不建议用此方法,__对Python有特殊意义
_protected # 保护类型,类对象和子类对象可以调用,建议用这种方式定义特别的属性方法

lass Person5:
    def __p(self):
        print("这是私有属性") #内部函数也同样可以任意之间互相调用
    def p1(self):
        print("这是p1不是私有方法")
    def p2(self):
        print("这是p2,可以调用p1,也可以调用私有方法__p")
        self.p1()
        self.__p()
#创建对象
c1 = Person5()
c1.p1()
c1.p2()
#c1.__p() #不能直接私有函数。报错。注意区分系统自带的函数如__str__,外部可以直接调用的。
 
"""结果如下:
这是p1不是私有方法
这是p2,可以调用p1,也可以调用私有方法__p
这是p1不是私有方法
这是私有属性
"""

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

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass
class Animal:
    """
    人和狗都是动物,所以创造一个Animal基类
    """
    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 人和狗都有自己的昵称;
        self.aggressivity = aggressivity  # 人和狗都有自己的攻击力;
        self.life_value = life_value  # 人和狗都有自己的生命值;

    def eat(self):
        print("%s is eating"%self.name)

class Dog(Animal):
    pass

class Person(Animal):
    pass

egg = Person("egon",10,1000)
ha2 = Dog("二愣子",50,1000)
egg.eat()
ha2.eat()

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

方法重写
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,实例如下:

#此示例示意覆盖的含义及方法
class A:
    def work(self):
        print("A.work被调用")
class B(A):
    """B类继承子A类"""
    def work(self):
        print("B.work被调用")
 
b = B()
b.work()    #B.work被调用
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » Python学习笔记8:面向对象