python学习笔记:类与对象、魔法方法、继承(一)

一、类与对象

类:
类是同一类对象的属性和行为的抽象和总结;
类描述同一类对象应包含的数据;
类描述同一类对象的行为特征;
类是抽象的,是一个概念模型;
一个类可以找到多个对象;

对象:
具有明确的属性和行为;
程序是对象的集合,通过消息交互。

类和对象关系:
类就是创建对象的模板;
对象就是根据类产生的一个具体实例。

1.1、类的定义

类(Class)由3部分构成:

  • 类的名称 : 类名
  • 类的属性 : 一组数据
  • 类的方法 : 允许对进行操作的方法 (行为)

定义格式:

class 类名:
	方法列表

示例:

class Hero(object):
    def info(self):
        print("hello world")

self 代表类的实例,而非类

  1. 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
  2. 所谓的self,可以理解为自己可以把self当做C++中类里面的this指针一样理解,就是对象自身的意思
  3. 某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可。

1.2、对象的定义

定义格式:

对象名 = 类名()

示例:

class Hero(object):
    def info(self):
        """
        当对象调用方法的时候,python会把第一个参数传递到我们的self中
        """
        print(self)
        print("---"*20)

# 实例化对象
test1 = Hero()

# . 表示选择属性或者方法
# 调用info方法
test1.info()

print(test1)
print(id(test1))
print(Hero.info)

"""
运行结果为:
<__main__.Hero object at 0x0000000001DD8400>
------------------------------------------------------------
<__main__.Hero object at 0x0000000001DD8400>
31294464
<function Hero.info at 0x0000000001E28700>
"""

1.3、给对象添加属性

class Hero(object):
    def info(self):
        print("info_function")

# 实例化对象
test1 = Hero()

# 给对象添加属性以及对应的属性值,如果不添加就会报错
test1.name = "张三"
test1.age = 16

print("name = %s, age = %d" % (test1.name, test1.age))

"""
运行结果为:
name = 张三, age = 16
"""

1.4、通过self方法获取对象属性

class Hero(object):
    def info(self):
        print("name = %s, age = %d" % (self.name, self.age))

test1 = Hero()

# 给对象添加属性以及对应的属性值,如果不添加就会报错,这里就引入了魔法方法
test1.name = "张三"
test1.age = 16

test1.info()

"""
运行结果为:
name = 张三, age = 16
"""

二、魔法方法

创建对象后再去添加属性有点不合适,有没有简单的办法,可以在创建对象的时候,就已经拥有这些属性?——魔法方法

2.1、类的初始方法——init方法

在创建对象的时候,自动调用__init__()函数,自动完成对象属性的设置。(类似于C++中的构造函数)

语法格式一:不带参数

def __init__(self):
	slef.属性1 = 属性值1
	slef.属性2 = 属性值2
	...

语法格式二:带参数

def __init__(self, 参数1, ..., 参数n):
	slef.属性1 = 参数1
	...
	slef.属性n = 参数n

示例:不带参数

class Car(object): # 类名第一个字符一般大写

    # 初始化方法
    def __init__(self):
        self.wheel = 4
        self.color = "blue"

    def info(self):
        print("车轮数:%s, 颜色:%s" % (self.wheel, self.color))


BMW = Car()
BMW.info()

"""
运行结果为:
车轮数:4, 颜色:blue
"""

示例:带参数

class Car(object):  # 类名第一个字符一般大写

    # 初始化方法
    def __init__(self, wheel, color):
        self.wheel = wheel
        self.color = color

    def info(self):
        print("车轮数:%s, 颜色:%s" % (self.wheel, self.color))


# 对象1
BMW = Car(4, "白色")
BMW.info()

# 对象2
BMW1 = Car(4, "黄色")
BMW1.info()

"""
运行结果为:
车轮数:4, 颜色:白色
车轮数:4, 颜色:黄色
"""

2.2、类的字符信息输出——str方法

当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据。(必须return 一个字符串

当打印对象的时候,就是执行__str__()函数中的语句以及打印return的字符串。

语法格式:

def __str__(self):
	msg = "xxx"
	return msg

字符串赋值新用法:
wheel = str(4)
color = “blue”
a = “车轮数:%s, 颜色:%s” % (wheel, color) # 新用法
b = “车轮数:”+ wheel + ", " + “颜色:” + color # 新用法
print(a)
print(b)

示例:

class Car(object):  # 类名第一个字符一般大写

    # 初始化方法
    def __init__(self, wheel, color):
        self.wheel = wheel
        self.color = color

    def info(self):
        print("车轮数:%s, 颜色:%s" % (self.wheel, self.color))

    def __str__(self):
        msg = "车轮数:%s, 颜色:%s" % (self.wheel, self.color)
        return msg

BMW = Car(4, "白色")
print(BMW)

"""
运行结果为:
车轮数:4, 颜色:白色
"""

2.3、类的析构方法——del方法

在删除对象的时候,自动调用__del__()函数。(类似于C++中的析构函数)

语法格式:

def __del__(self):
	pass # 占位符

示例:

class Animal(object):
    def __init__(self, name): # 创建对象时自动调用
        print("__init__方法被调用")
        self.name = name

    def __del__(self): # 脚本结束时,自动调用
        print("__del__方法被调用")
        print("%s对象已经被删除" % self.name)


dog = Animal("狗")
a = 1
del a
del dog  # 手动删除
# 当没有del dog语句时,在脚本结束时,也会调用__del__()函数

"""
运行结果为:
__init__方法被调用
__del__方法被调用
狗对象已经被删除
"""

注意:

  • 当有1个变量保存了对象的引用时,此对象的引用计数就会加1
  • 当使用del删除变量指向的对象时,如果对象的引用计数不是1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除。

示例:

class Animal(object):
    def __init__(self, name): # 创建对象时自动调用
        print("__init__方法被调用")
        self.name = name

    def __del__(self): # 脚本结束时,自动调用
        print("__del__方法被调用")
        print("%s对象已经被删除" % self.name)

# 情况一
dog = Animal("狗") # 变量引用了对象一次
a = dog  # 变量引用了对象一次,总共引用了2次
del dog

while 1:
    pass   # 循环语句中,不允许空语句,所以加占位符

"""
运行结果为:(此时脚本并没有退出)
__init__方法被调用
"""
# 情况二
dog = Animal("狗") # 变量引用了对象一次
# a = dog
del dog # 对象总共被引用了一次

while 1:
    pass   # 循环语句中,不允许空语句,所以加占位符

"""
运行结果为:(此时脚本并没有退出)
__init__方法被调用
__del__方法被调用
狗对象已经被删除
"""

三、继承

3.1、单继承

示例:

class Master(object):
    def __init__(self):
        self.konfu = "古法"

    def make_cake(self):
        print("按照%s制作cake" % self.konfu)

# 定义Prentice类,继承自Master,就有了父类的属性和方法;Master是父类,Prentice是子类
class Prentice(Master):
    pass  # 占位符


cat = Prentice()  # 子类的实例化对象

print(cat.konfu)
cat.make_cake()

"""
运行结果为:
古法
按照古法制作cake
"""

3.2、多继承

class Master(object):
    def __init__(self):
        self.kongfu = "古法"

    def make_cake(self):
        print("按照%s制作cake" % self.kongfu)

    def master(self):
        print("master")


class School(object):
    def __init__(self):
        self.kongfu = "现代配方"

    def make_cake(self):
        print("按照%s制作cake" % self.kongfu)

    def school(self):
        print("school")

class Prentice(Master, School): # 多继承,继承多个父类,Master在前
    pass

cat = Prentice()
print(cat.kongfu)
cat.make_cake()


# 子类的魔法属性__mro__决定了属性和方法的查找顺序
print(Prentice.__mro__)

cat.master() # 不重名不受影响
cat.school()

"""
运行结果为:
古法
按照古法制作cake
(<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
master
school
"""

注意:

  1. 当多个父类中存在相同的属性和方法时,子类调用属性和方法按继承的先后顺序进行查找。(左边优先查找
  2. 子类的魔法属性__mro__决定了属性和方法的查找顺序。查看方式为print(子类.__mro__)
  3. 不重名的属性和方法不受影响。

猜你喜欢

转载自blog.csdn.net/weixin_42258222/article/details/106879758