类和实例(38)

作者: 程序员夏天 | 来源:发表于2020-03-10 23:49 被阅读0次

类,英文名字Class,有“类别”,“分类”,“聚类”的意思。必须牢记类是抽象的模板,用来描述具有相同属性和方法的对象的集合,比如Animal类。而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

Python使用class关键字来定义类,其基本结构如下:

class 类名(父类列表):
    pass

类名通常采用驼峰式命名方式,尽量让字面意思体现出类的作用。Python采用多继承机制,一个类可以同时继承多个父类(也叫基类、超类),继承的基类有先后顺序,写在类名后的圆括号里。继承的父类列表可以为空,此时的圆括号可以省略。但在Python3中,即使你采用类似class Student:pass的方法没有显式继承任何父类的定义了一个类,它也默认继承object类。因为,object是Python3中所有类的基类。

下面是一个学生类:

class Student:
    classroom = '101'
    address = 'beijing' 

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def print_age(self):
        print('%s: %s' % (self.name, self.age))

可以通过调用类的实例化方法(有的语言中也叫初始化方法或构造函数)来创建一个类的实例。默认情况下,使用类似obj=Student()的方式就可以生成一个类的实例。但是,通常每个类的实例都会有自己的实例变量,例如这里的name和age,为了在实例化的时候体现实例的不同,Python提供了一个def init(self):的实例化机制。任何一个类中,名字为init的方法就是类的实例化方法,具有init方法的类在实例化的时候,会自动调用该方法,并传递对应的参数。比如:

li = Student("李四", 24)
zhang = Student("张三", 23)

实例变量和类变量

实例变量:

实例变量指的是实例本身拥有的变量。每个实例的变量在内存中都不一样。Student类中init方法里的name和age就是两个实例变量。通过实例名加圆点的方式调用实例变量。

我们打印下面四个变量,可以看到每个实例的变量名虽然一样,但他们保存的值却是各自独立的:

print(li.name)
print(li.age)
print(zhang.name)
print(zhang.age)
------------------------
李四
24
张三
23

类变量:

定义在类中,方法之外的变量,称作类变量。类变量是所有实例公有的变量,每一个实例都可以访问、修改类变量。在Student类中,classroom和address两个变量就是类变量。可以通过类名或者实例名加圆点的方式访问类变量,比如:

Student.classroom
Student.address
li.classroom
zhang.address

在使用实例变量和类变量的时候一定要注意,使用类似zhang.name访问变量的时候,实例会先在自己的实例变量列表里查找是否有这个实例变量,如果没有,那么它就会去类变量列表里找,如果还没有,弹出异常。

Python动态语言的特点,让我们可以随时给实例添加新的实例变量,给类添加新的类变量和方法。因此,在使用li.classroom = '102'的时候,要么是给已有的实例变量classroom重新赋值,要么就是新建一个li专属的实例变量classroom并赋值为‘102’。看下面的例子:

>>> class Student:              # 类的定义体
    classroom = '101'           # 类变量
    address = 'beijing'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def print_age(self):
        print('%s: %s' % (self.name, self.age))


>>> li = Student("李四", 24)        # 创建一个实例
>>> zhang = Student("张三", 23)     # 创建第二个实例
>>> li.classroom # li本身没有classroom实例变量,所以去寻找类变量,它找到了!
'101'
>>> zhang.classroom # 与li同理
'101'
>>> Student.classroom   # 通过类名访问类变量
'101'
>>> li.classroom = '102'    # 关键的一步!实际是为li创建了独有的实例变量,只不过名字和类变量一样,都叫做classroom。
>>> li.classroom    # 再次访问的时候,访问到的是li自己的实例变量classroom
'102'
>>> zhang.classroom # zhang没有实例变量classroom,依然访问类变量classroom
'101'
>>> Student.classroom   # 保持不变
'101'
>>> del li.classroom    # 删除了li的实例变量classroom
>>> li.classroom        # 一切恢复了原样
'101'
>>> zhang.classroom
'101'
>>> Student.classroom
'101'

类的方法:

Python的类中包含实例方法、静态方法和类方法三种方法。这些方法无论是在代码编排中还是内存中都归属于类,区别在于传入的参数和调用方式不同。在类的内部,使用def关键字来定义一个方法。

实例方法

类的实例方法由实例调用,至少包含一个self参数,且为第一个参数。执行实例方法时,会自动将调用该方法的实例赋值给self。self代表的是类的实例,而非类本身。self不是关键字,而是Python约定成俗的命名,你完全可以取别的名字,但不建议这么做。

例如,我们前面Student类中的print_age()就是实例方法:

def print_age(self):
        print('%s: %s' % (self.name, self.age))

# --------------------------
# 调用方法
li.print_age()
zhang.print_age()

静态方法

静态方法由类调用,无默认参数。将实例方法参数中的self去掉,然后在方法定义上方加上@staticmethod,就成为静态方法。它属于类,和实例无关。建议只使用类名.静态方法的调用方式。(虽然也可以使用实例名.静态方法的方式调用)

class Foo:

    @staticmethod
    def static_method():
        pass

#调用方法
Foo.static_method()

类方法

类方法由类调用,采用@classmethod装饰,至少传入一个cls(代指类本身,类似self)参数。执行类方法时,自动将调用该方法的类赋值给cls。建议只使用类名.类方法的调用方式。(虽然也可以使用实例名.类方法的方式调用)

class Foo:

    @classmethod
    def class_method(cls):
        pass

Foo.class_method()

看一个综合例子:

class Foo: 

    def __init__(self, name):
        self.name = name 

    def ord_func(self):
        """定义实例方法,至少有一个self参数 """
        print('实例方法')

    @classmethod
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print('类方法')

    @staticmethod
    def static_func():
        """ 定义静态方法 ,无默认参数"""
        print('静态方法') 

# 调用实例方法
f = Foo("Jack")
f.ord_func()
Foo.ord_func(f) # 请注意这种调用方式,虽然可行,但建议不要这么做!

# 调用类方法
Foo.class_func()
f.class_func()  # 请注意这种调用方式,虽然可行,但建议不要这么做!

# 调用静态方法
Foo.static_func()
f.static_func() # 请注意这种调用方式,虽然可行,但建议不要这么做!

类、类的方法、类变量、类的实例和实例变量在内存中是如何保存的?

类、类的所有方法以及类变量在内存中只有一份,所有的实例共享它们。而每一个实例都在内存中独立的保存自己和自己的实例变量。

创建实例时,实例中除了封装诸如name和age的实例变量之外,还会保存一个类对象指针,该值指向实例所属的类的地址。因此,实例可以寻找到自己的类,并进行相关调用,而类无法寻找到自己的某个实例。

image.png

上一篇:面向对象编程

下一篇:封装、继承和多态

小编创建了一个两千人的python交流群,有零基础和工作了的朋友交流,还有相关的电子书与视频下载,!群 : 877169862 ,欢迎进群学习交流

相关文章

  • 类和实例(38)

    类,英文名字Class,有“类别”,“分类”,“聚类”的意思。必须牢记类是抽象的模板,用来描述具有相同属性和方法的...

  • python零基础入门到实战,基础知识总结(二)

    33 类 34 类 汽车里程表 35 子类方法 init () 36 class实例 37 文件和异常 38 将数...

  • 跟我一起学Python(五)

    类和实例 类的定义和实例化 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的...

  • 类和实例

    类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Stud...

  • 类和实例

    学习Python的一些心得,如果不对,还望批评指正。 类:英文名字叫Class实例:英文名字叫Instance 类...

  • 类和实例

    类和实例: 定义一个类:class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(obje...

  • 类和实例

    类的特征 公有方法私有方法属性私有变量析构函数:(析构函数与构造函数相反,当对象结束其生命周期,如对象所在的函数已...

  • Python面向对象编程

    类和实例 面向对象最重要的概念就是类(class)和实例(instance),类是抽象的模板,而实例是根据类创建出...

  • Python实例变量和类变量

    Python实例变量和类变量 类变量(类属性): 类变量属于类所有,所有实例共享一个变量 实例变量(实例属性) 实...

  • 1.14类代码编写基础

    一、类对象和实例对象 在python对象模型中,类和通过类产生的实例是两种不同的对象类型: 类类是实例工厂。类的属...

网友评论

    本文标题:类和实例(38)

    本文链接:https://www.haomeiwen.com/subject/mnrodhtx.html