什么是类实例化

类对象就像是一个用来创建对象的工厂。

  • 创建一个新对象的过程叫做实例化 (instantiation)
  • 这个新对象叫做这个类的一个实例(instance)。

举个例子

  • 定义好了Student类,就可以根据Student类创建出Student的实例
    • Student()返回的是一个Student对象的引用,并将它赋值给bart
>>> bart = Student()
>>> bart
<__main__.Student object at 0x10a67a590>
  • 当你试图打印一个实例,Python 会告诉你它属于哪个类,以及它在内存中的存储地址。可以看到,
    • 变量bart指向的就是一个Student的实例
    • 后面的0x10a67a590是内存地址,每个object的地址都不一样

类对象的使用

定义的类只有进行实例化,也就是使用该类创建对象之后,才能使用,一般有两种操作:

  • 访问或修改类对象具有的实例变量,甚至可以添加新的实例变量或者删除已有的实例变量;
  • 调用类对象的方法,包括调用现有的方法,以及给类对象动态添加方法。

访问变量或方法

使用已创建好的类对象访问类中实例变量的语法格式如下:

类对象名.变量名

使用类对象调用类中方法的语法格式如下:

对象名.方法名(参数)

注意,对象名和变量名以及方法名之间用点 “.” 连接。

举个例子

class CLanguage :
    # 下面定义了2个类变量
    name = "C语言中文网"
    add = "http://c.biancheng.net"
    def __init__(self,name,add):
        #下面定义 2 个实例变量
        self.name = name
        self.add = add
        print(name,"网址为:",add)
    # 下面定义了一个say实例方法
    def say(self, content):
        print(content)
# 将该CLanguage对象赋给clanguage变量
clanguage = CLanguage("C语言中文网","http://c.biancheng.net")
#输出name和add实例变量的值
print(clanguage.name,clanguage.add)
#修改实例变量的值
clanguage.name="Python教程"
clanguage.add="http://c.biancheng.net/python"
#调用clanguage的say()方法
clanguage.say("人生苦短,我用Python")
#再次输出name和add的值
print(clanguage.name,clanguage.add)

动态添加/删除实例变量

通过直接增加一个新的实例变量并为其赋值,就能为已创建好的对象动态增加实例变量

# 为clanguage对象增加一个money实例变量
clanguage.money= 159.9
print(clanguage.money)

通过del语句即可动态删除属性

#删除新添加的 money 实例变量
del clanguage.money
#再次尝试输出 money,此时会报错
print(clanguage.money)

运行程序会发现,结果显示 AttributeError 错误:

Traceback (most recent call last):
  File "C:/Users/mengma/Desktop/1.py", line 29, in <module>
    print(clanguage.money)
AttributeError: 'CLanguage' object has no attribute 'money'

动态添加方法

Python 也允许为对象动态增加方法。但是要注意的是,Python 不会自动将调用者自动绑定到第一个参数(即使将第一个参数命名为 self 也没用)。例如如下代码:

# 先定义一个函数
def info(self):
    print("---info函数---", self)
# 使用info对clanguage的foo方法赋值(动态绑定方法)
clanguage.foo = info
# Python不会自动将调用者绑定到第一个参数,
# 因此程序需要手动将调用者绑定为第一个参数
clanguage.foo(clanguage)  # ①

# 使用lambda表达式为clanguage对象的bar方法赋值(动态绑定方法)
clanguage.bar = lambda self: print('--lambda表达式--', self)
clanguage.bar(clanguage) # ②

上面的第 5 行和第 11 行代码分别使用函数、lambda 表达式为 clanguage 对象动态增加了方法,但对于动态增加的方法,Python 不会自动将方法调用者绑定到它们的第一个参数,因此程序必须手动为第一个参数传入参数值,如上面程序中 ① 号、② 号代码所示。

那能不能不用手动给 self 传值的方法呢?通过借助 types 模块下的 MethodType 可以实现,仍以上面的 info() 函数为例:

def info(self,content):
    print("C语言中文网地址为:%s" % content)
# 导入MethodType
from types import MethodType
clanguage.info = MethodType(info, clanguage)
# 第一个参数已经绑定了,无需传入
clanguage.info("http://c.biancheng.net")

可以看到,由于使用 MethodType 包装 info() 函数时,已经将该函数的 self 参数绑定为 clanguage,因此后续再使用 info() 函数时,就不用再给 self 参数绑定值了。

如何知道类对象的类型

  • 如果你不确定一个对象的类型,你可以询问:
>>> type(bart)
<class '__main__.Student'>
  • 你也可以用 isinstance 来检查某个对象是不是某个类的实例。
>>> isinstance (bart , Student)
True

>>> a = 111
>>> isinstance(a, int)
True

isinstance 和 type 的区别在于:

  • type()不会认为子类是一种父类类型。
  • isinstance()会认为子类是一种父类类型。

内置类属性

object 为 Python 所有类的默认父类,都继承于它,这样你就拥有了好多可操作的基础对象,可以使用dir(Student)查看,里边的部分方法给我们提供一个框架,我们可以按它的格式实现一些功能。

class Student(object):
    """这是一个学生类"""
    def __init__(self, name):
        self.name = name

    def say(self):
        print(f'我的名字是:{self.name}')

    def add(self, x, y):
        print(f'这个加法我会,等于{x+y}')

我们可以看这个类的简介:

tom.__doc__
# '这是一个学生类'

其他的:

tom.__dict__ # 查看类的属性,是一个字典
tom.__name__ # 类名
tom.__module__ # 类定义所在的模块

如何确定一个类有哪些属性?

  • 如果你不确定一个对象是否拥有某个属性,你可以使用内置函数 hasattr 检查:
    • 第一个参数可以是任何对象;
    • 第二个参数是一个字符串 ,代表了某个属性的名字。
>>> hasattr (bart  , 'name')
False
  • 你也可以使用 try 语句来检查某个对象是不是有你需要的属性:
try :
	name = p.name
except AttributeError :
	name = 0
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐