11.类和对象,面向对象,self,魔法方法

类和对象

编程语言分类:
    编译型语言   解释型语言

    面向过程语言:  c
    面向对象语言: java  python  c++ c#  php   javascript

    面向过程:注重过程  我们是执行者
    面向对象:注重结果  我们是调用者
    面向对象的本质还是面向过程
    
        类:   类又叫模板
    对象: 又叫实例  是根据类创建出来的

    创建一个类需要一个关键字:
    class

    根据类创建对象:
    对象名 = 类名()
    对象名 = 类名()

类是对一群具有相同特征或者行为 的事物的一个统称,是抽象的,不能直接使用

  • 特征其实就是一个变量,在类里我们称之为属性。
  • 行为其实就是一个函数,在类里我们称之为方法。
  • 类其实就是由 属性方法 组成的一个抽象概念。

对象

对象是由类创建出来的一个具体存在,可以直接使用。由哪一个类创建出来的 对象,就拥有在哪一个类中定义的属性和方法。 对象 就相当于用图纸制造的飞机。在开发中,应该先有类,在类里定义好属性和行为,再根据类来创建对象

class Dog:
    def __init__(self, name, sex, age, color):
        self.name = name
        self.sex = sex
        self.age = age
        self.color = color

    def look_door(self):
        print("%s能看门" % self.name)

    def eat(self):
        print("%s吃骨头" % self.name)


dog1 = Dog('狗蛋子', '公', '3岁', '黄色')
dog1.look_door()
dog1.eat()


dog2 = Dog('二愣子', '母', '4岁', '灰色')
dog2.look_door()
dog2.eat()

关系

  • 类是模板,对象是根据类这个模板创建出来的,应该先有类,再有对象。
  • 使用同一个类,能够创建出很多对象。
  • 类中定义了什么属性和方法,对象中就有什么属性和方法。
  • 不同对象对应的属性值也会不同。

在程序开发中,要设计一个类,通常需要满足一下三个要素:

  1. 类名 这类事物的名字,安照大驼峰命名法(每个单词的首字母大写)起名。
  2. 属性 这类事物具有什么样的特征。
  3. 方法 这类事物具有什么样的行为。

定义类名

名词提炼法:分析整个业务流程,出现的名词,通常就是找到的类。

属性和方法的确定

  • 对对象的特征描述,可以定义成属性
  • 对象具有的行为(动词)可以定义成方法属性和方法的确定
    • 对对象的特征描述,可以定义成属性
    • 对象具有的行为(动词)可以定义成方法

面向对象

在Python中,对象几乎是无处不在的,我们可以使用dir内置函数来查看这个对象里的方法。

class Person:
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.height = height

    def run(self, flag):
        if flag:
            print(f"{self.name}跑会步")
        else:
            print(f"{self.name}不喜欢跑步")

    def eat(self):
        print("吃东西")


p1 = Person('小明', '18', '1.75')
p1.run(True)
p1.eat()


p2 = Person('小美', '17', '1.65')
p2.run(False)
p2.eat()

print(dir(p1))

定义类

在Python中要定义一个只包含方法的类,语法格式如下:

class 类名:
    def 方法1(self,参数列表):
        pass
    def 方法2(self,参数列表):
        pass
"""
方法的定义格式和之前学习过的函数一样
方法里的第一个参数必须是self,大家暂时先记住,稍后介绍 self.
类名要遵守大驼峰命名法。
"""

创建实例对象

当一个类定义完成之后,要使用这个类来创建对象,语法格式如下:

对象变量名 = 类名()

列子

class Cat:
    """这是个猫类"""

    def eat(self):
        print("小猫在吃东西")

    def drink(self):
        print("小猫在喝水")

tom = Cat()  # 创建了一个Cat对象
tom.eat()
tom.drink()

hello_kitty = Cat()  # 又创建了一个新的Cat对象
hello_kitty.eat()
hello_kitty.drink()

self的使用

给对象添加属性
python支持动态属性,当一个对象创建好了以后,直接使用 对象.属性名 = 属性值 就可以很方便的给对象添加一个属性。

# 这种方法很方便,但是,不建议使用这种方式给对象添加属性。
tom = Cat()
tom.name = 'Tom'  # 可以直接给 tom 对象添加一个 name 属性

self的概念

哪个对象调用了方法,方法里的self指的就是谁。 通过 self.属性名 可以访问到这个对象的属性;通过 self.方法名() 可以调用这个对象的方法。

class Cat:
    def eat(self):
        print("%s爱吃鱼" %self.name)

tom = Cat()
tom.name = 'Tom'  # 给 tom 对象添加了一个name属性
tom.eat()  # Tom爱吃鱼

lazy_cat = Cat()
lazy_cat.name = "大懒猫"
lazy_cat.eat() # 大懒猫爱吃鱼

在日常开发中,不推荐在类的外部直接给对象添加属性这种方式。对象应该具有哪些属性,我们应该封装在类的内部。

魔法方法

Python 里有一种方法,叫做魔法方法。Python 的类里提供的,两个下划线开始,两个下划线结束的方法,就是魔法方法,魔法方法在恰当的时候就会被激活,自动执行。 魔法方法的两个特点:

  • 两侧各有两个下划线;
  • "咒语"名字已经由 Python 官方定义好,我们不能乱写。

不太能理解到底啥是魔法方法

## __init__方法

初始化值
__init__()方法,在创建一个对象时默认被调用,不需要手动调用。在开发中,如果希望在创建对象的同时,就设置对象的属性,可以对 __init__ 方法进行改造。

class Cat:
    """这是一个猫类"""
    def __init__(self,name):  # 重写了 __init__ 魔法方法
        self.name = name

    def eat(self):
        return "%s爱吃鱼"%self.name
    def drink(self):
        return '%s爱喝水'%self.name

    """
        tom = Cat()
        TypeError: __init__() missing 1 required positional argument: 'name'
        这种写法在运行时会直接报错!因为 __init__ 方法里要求在创建对象时,必须要传递 name 属性,如果不传入会直接报错!
    """

tom = Cat("Tom")  # 创建对象时,必须要指定name属性的值
tom.eat()   # tom爱吃鱼


#注意
"""
1.__init__()方法在创建对象时,会默认被调用,不需要手动的调用这个方法。
2.__init__()方法里的self参数,在创建对象时不需要传递参数,python解释器会把创建好的对象引用直接赋值给self
3.在类的内部,可以使用self来使用属性和调用方法;在类的外部,需要使用对象名来使用属性和调用方法。
4.如果有多个对象,每个对象的属性是各自保存的,都有各自独立的地址。
5.方法是所有对象共享的,只占用一份内存空间,方法被调用时会通过self来判断是哪个对象调用了实例方法。
"""

__del__方法

前期没啥用,到后期用刀数据流就会有用啦
创建对象后,python解释器默认调用__init__()方法;

而当删除对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法。

class Student:
    def __init__(self,name,score):
        print('__init__方法被调用了')
        self.name = name
        self.score = score

    def __del__(self):
        print('__del__方法被调用了')
s = Student('lisi',95)
del s
input('请输入内容')

.__str__方法

可以吧本来输出为地址或者是其他东西的输出, 变为输出字符串
__str__方法返回对象的描述信息,使用print()函数打印对象时,其实调用的就是这个对象的__str__方法。

class Cat:
    def __init__(self,name,color):
        self.name = name
        self.color = color

tom = Cat('Tom','white')

# 使用 print 方法打印对象时,会调用对象的 __str__ 方法,默认会打印类名和对象的地址名
print(tom)   # <__main__.Cat object at 0x0000021BE3B9C940>


#如果想要修改对象的输出的结果,可以重写 __str__ 方法。
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __str__(self):
        return '哈哈'

p  = Person('张三',18)
print(p)   # 哈哈  打印对象时,会自动调用对象的 __str__ 方法

#一般情况下,我们在打印一个对象时,可能需要列出这个对象的所有属性。
class Student:
    def __init__(self,name,score):
        self.name = name
        self.score = score
    def __str__(self):
        return '姓名是:{},成绩是{}分'.format(self.name,self.score)

s = Student('lisi',95)
print(s)   # 姓名是:lisi,成绩是95分
class Book:
    def __init__(self, name, price, author):
        self.name = name
        self.price = price
        self.author = author

    def look(self, uname):
        print(f"{uname}正在看{self.name}")

    def __str__(self):
        return self.name + "--" + self.price + "--" + self.author

    def __call__(self, *args, **kwargs):
        self.look(args[0])
        print("hello world")


b = Book('三体', '180$', '刘慈欣')

# b('haha')

print(b)

repr__方法

有__str__方法就用,这个和str方法差不多,建议优先使用str方法
__repr__方法和__str__方法功能类似,都是用来修改一个对象的默认打印内容。在打印一个对象时,如果没有重写__str__方法,它会自动来查找__repr__方法。如果这两个方法都没有,会直接打印这个对象的内存地址。

__call__方法

对象后面加括号,触发执行。

class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print('__call__')


obj = Foo()  # 执行 __init__
obj()  # 执行 __call__

总结

当创建一个对象时,会自动调用__init__方法,当删除一个对象时,会自动调用__del__方法。
使用__str__和__repr__方法,都会修改一个对象转换成为字符串的结果。一般来说,__str__方法的结果更加在意可读性,而__repr__方法的结果更加在意正确性(例如:datetime模块里的datetime类)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值