Python面向对象、各种名词解释(类、对象、实例、实例化)、__init__方法、__del__方法、__str__方法、设计类时候的一些惯例

一、类和对象的含义、二者关系

1、类

类就是一群具有相同特征或者行为的事物的一个统称,是抽象的,并且不能直接使用,需要创建一个对象。比如,人、动物就是一个类。类的特征被称为属性,类的行为动作被称为方法

对于人这个类来说,人的身高、体重、姓名、年龄就是人的属性;而人能吃喝拉撒睡、能跑、能跳就是人的方法对于动物这个类来说,动物的颜色、体重就是它的属性,动物能吃能睡能跑能跳就是它的方法

再抽象点,类就好比是制造汽车、轮船时候画出来的图纸,我们把汽车/轮船的尺寸大小、长宽、几个轮子几个窗户画在图纸上,那么这些就是它的属性。而按照图纸最终制造出来的汽车,能开能走能转弯这些就是它的方法。这些最终根据图纸制造出来的汽车就叫对象。

2、对象

对象就是由类创建出来的一个具体存在,可以直接使用。一个类,可以创建出来很多个对象,每个对象的属性的值,可能会不一样。由哪一个类创建出来的对象,就拥有那个类里面所定义的属性和方法。比如,张三、李四这些都是人这个类的对象,他们都有身高体重年龄(这就叫拥有类里面的属性),他们都能吃喝拉撒睡、能跑能跳(这就叫拥有类里面的方法)。

3、对象和类的关系

(1)先有类,再有对象。直白点来说,类是模板,而对象是根据类这个模板创建出来的。

(2)类只有一个,而对象可以有很多个。(比如,张三、李四就是对象,他们都属于人这一个类。再比如,根据汽车图纸可以制造出来成千上万台汽车。)

(3)不同的对象之间,属性的值可能会不一样。(比如,张三、李四、名字不一样,身高、体重、年龄可能都不一样。再比如,汽车造出来了,但它的颜色可能会不一样,有的是黑色,有的是白色。但功能、性能、外观尺寸这些都是一样的。)

(4)类里面定义了什么属性和方法,那么对象中就有什么属性和方法

二、类的设计

面向对象编程中,首先需要设计类,对于类的设计,需要明白的是,如何设计一个类?通常包含三个要素:类名、属性、方法。

1、类名就是这类事物的名字。比如,人就是一个类。

2、属性——类里面的变量

这类事物都有哪些特征?这就是属性,比如,人名、身高、体重、性别就是属性。说白了,属性就是一个变量,把这个变量放到类里面,称呼就变了,就不叫变量了,得叫属性。这样的叫法是为了在程序中能更好的和普通变量进行区分。属性一般是个名称,是个名词,比如:颜色、身高、名字。

3、方法——类里面的函数

这类事物都有哪些行为?这就是方法。比如,人能吃喝拉撒睡、能跑能跳,这就是方法。说白了,方法就是一个函数。在类里面出现的函数就叫方法。这样叫法是为了在一个程序中,能更好的和普通函数进行区分。方法一般是个动作,是个动词,比如:跑、跳、走。

技巧在类里面出现的变量叫属性,在类里面出现的函数叫方法

三、类的实现——利用class关键字创建一个类

语法格式:

class 类名:    # 大驼峰法

        def __init__(self,参数1="默认值1",参数2="默认值2",....):

                self.参数1=参数1        # 定义属性、给类添加属性

                self.参数2=参数2

        def 方法1(self,参数1,参数2...): # 定义方法

                要执行的代码

对象名=类名(参数1,参数2....)    # 创建一个对象

对象名.方法1(参数1,参数2...)

对象名.参数1=值

注意:方法的定义和普通函数一模一样,不同的是,方法的第一个参数必须是self,这是python语法规定的。self就表示调用方法的对象自己。

举例:定义一个Person类,它有name属性,eat方法。

class Person:  # 定义一个person类
    def __init__(self, name="张三"):  # 初始化方法中,定义一个形参name
        self.name = name  # self.name中的name表示一个属性,名字叫name,而等号后面的name表示形参

    def eat(self):  # 定义一个eat方法
        print("%s在吃饭" % self.name)  # 调用name属性


p1 = Person("李四")  # 创建一个对象,名字叫p1,后面的李四就是实参,把它赋给形参name
p1.eat()
p2 = Person()  # 又创建了个对象,名字叫p2,()里面啥都没写,表示取默认值,张三
p2.eat()

结果:
李四在吃饭
张三在吃饭

解析:
(1)在上面的代码中,就很好的体现了,类只有一个,对象可以有多个,也体现了,不同的对象之间属性可能不相同。(即:都有name属性,但一个叫张三一个叫李四)。

(2)__init__(self)是个初始化方法,一般常用来定义属性。这样的好处是,在创建完对象之后,能自动调用这个方法。

(3)定义方法时,第一个形参必须是self

(4)在类的内部,无论是定义属性,还是调用属性,属性名前面要加self ,只有这样才叫属性。

此外,在调用方法的时候(也就是方法的嵌套,即一个方法里面嵌套另外一个方法),也要加self。

例如:初始化方法中定义name属性,eat方法中,调用这个属性,demo方法中调用eat方法

class Person:  
    def __init__(self, name="张三"):  
        self.name = name  # self.name表示一个属性,等号后面的name表示形参

    def eat(self):  # 定义一个eat方法
        print("%s在吃饭" % self.name)  # 调用属性

    def demo(self):
        self.eat()   # 方法里面调用方法——方法的嵌套


p = Person()
p.demo()

结果:
张三在吃饭

(5)类是静态的,只有创建为对象后,才能称为动态运行的程序。

(6)在类的外部对象在调用类的属性或者方法时不加self。直接对象名.属性名=值或对象名.方法名(参数) 。

例如:

class Person:
    def __init__(self, name="张三"):
        self.name = name  

    def eat(self):  # 定义一个eat方法
        print("%s在吃饭" % self.name)  # 调用属性

    def demo(self):
        self.eat()  # 方法里面调用方法——方法的嵌套


p = Person()
p.name = "小明"  # 对象调用类的属性
p.demo()  # 对象调用类的方法

结果:
小明在吃饭

注意:这种写法p = Person("小明")和p = Person()    p.name = "小明"结果是一样的。第一种写法是,直接在实例化时候就写了实参,然后传递给形参name,而第二种是调用name属性再赋值,结果是一样的。

带缺省值的形参:当函数被调用时,如果有实参,就采用实参的值,如果没有实参,那就采用缺省值(也就是自己的默认值)。

(7)实例就是通过类创建出来的对象,就叫类的实例。

实例化:创建对象的这个动作就叫实例化。比如,敲p1 = Person()这行代码的这个过程,就叫实例化。

所以,实例化的结果就是,创建出来了一个对象。而这个对象呢,就叫类的实例。

四、类里内置的方法

1、__init__  ——用来给类添加属性、定义类中的属性

class Dog:
    def __init__(self):     # 不带形参
        print("Dog被创建了")


a = Dog()
结果:
Dog被创建了


# 带形参
class Dog:
    def __init__(self, name="二哈"):
        self.name = name
        print("%s被创建了" % self.name)


d1 = Dog()  # 不带实参,形参将用默认值
d2 = Dog("柯基")  # 带实参,实参将把值传递给形参

结果:
二哈被创建了
柯基被创建了


#注意:这里的形参name也可以改成其它名字,比如a(但不建议改),因为这里用name只是一种习惯,一般大家都是这么用的。
class Dog:
    def __init__(self, a="二哈"):
        self.name = a
        print("%s被创建了" % self.name)


d1 = Dog()   # 创建第一个对象
d2 = Dog("柯基")  # 创建第二个对象
结果:
二哈被创建了
柯基被创建了

注意:

(1)__init__注意写法,前面后面各两个下划线

(2)当实例化对象的时候(也就是使用类名( )创建对象),init方法会自动被调用

(3)init方法一旦有形参实例化对象的时候就必须提供实参否则报错。但通常情况下,为了避免报错init在定义形参的时候,都会带个缺省值。这样的话,无论实例化时候带不带实参,代码都不会报错,从而增加了代码的灵活性。

(4)init方法最大的用途就是用来给类添加属性。也就是在初始化方法中,定义类的属性。

(5)init方法中,self后面可以有多个形参。

2、__del__  ——当对象从内存销毁前,再执行一些代码

(1)del方法只有一个参数self 。

(2)当对象在内存中被销毁的时候,系统自动调用del方法。

(3)对象即使没有定义del方法,程序运行完毕后也是会被销毁,只是说,定义del的话,能在代码执行结束前,或者叫,当对象从内存中销毁的时候,再来帮我们输出点东西,并不是说,没有del方法对象就不会被销毁了。

(4)如果对象是局部变量,那么函数执行完毕,就会自动调用对象的del方法。

如果对象是全局变量,那么程序执行完毕,就会自动调用对象的del方法。

例如:

class Dog:
    def __init__(self, name="二哈"):
        self.name = name
        print("%s被创建了" % self.name)

    def eat(self):
        print("%s在吃东西" % self.name)

    def __del__(self):      # 在对象被销毁前,再下输出点东西
        print("%s被销毁了" % self.name)


def test():  # 在类的外面定义一个函数
    d = Dog()  # 创建一个对象,名字叫d,d也是一个局部变量
    d.eat()  # 调用类的方法


test()  # 程序的第一条执行语句
a = Dog("柯基")  # 再创建一个对象,名字叫a,a也是一个全局变量, 该对象带实参,实参将把值传递给形参

结果:
二哈被创建了
二哈在吃东西
二哈被销毁了
柯基被创建了
柯基被销毁了

3、__str__ ——print(对象名)时候,可以显示一些想要的信息,而不是显示内存空间

当把对象直接放到print里面进行输出的时候,显示的是对象在内存中的地址编号。

例如:

class Dog:
    def __init__(self, name="大黄"):
        self.name = name

d = Dog()
print(d)
结果:
<__main__.Dog object at 0x000002343681D898>

显然用途不大,怎么让它显示我们想要的东西呢?此时就可以用str方法。

例如:我们想在打印对象的时候,让它输出属性值。

class Dog:
    def __init__(self, name="大黄"):
        self.name = name

    def __str__(self):  # str方法,必须返回一个字符串
        return self.name


d = Dog()
print(d) 

结果:
大黄

注意:

(1)str方法跟del方法一样,只有一个参数self

(2)str方法中,必须要有return,且return返回的必须是一个字符串

(3)如果类里面没有str方法,那么把实例化后的对象用print( )函数进行输出,显示的是对象的内存地址。而把类里面加上str方法,此时再把实例化后的对象用print( )函数进行输出,此时显示的就是str方法中,return返回的字符串,也就是我们想让它显示的内容了。

即:str方法主要用来,在print(对象名)时候,能够显示我们想要的东西,而不是让它单纯的显示对象的内存地址。

例如:用str与不用str的区别。

class Dog:
    def __str__(self):      # 加str方法
        return "这个类的名字叫Dog"


a = Dog()
print(a)

结果:
这个类的名字叫Dog



# 不加str方法
class Dog:
    def __init__(self):
        pass


a = Dog()
print(a)

结果:
<__main__.Dog object at 0x000002BA3D646668>

五、设计类的时候常用的一些套路、习惯、惯例

在定义类里面的方法时候,常有一些习惯,比如:在类当中,如果想得到一个属性的值,那么方法名就叫get_属性名,然后在方法中,再结合return;如果想设置一个属性的值话,那方法名就叫set_属性名;如果想显示一个属性的值话,那方法名就叫show_属性名(self,参数1,参数2...)

例如:

class Dog:
    def __init__(self, name="柯基"):
        self.name = name

    def get_name(self):  # 在设计类的时候,如果想通过方法得到一个属性的值,一般都是get_属性名
        return self.name  # !!

    def set_name(self, name):  # 如果想通过方法,设置一个属性的值话那就是,set_属性名(selg,形参)
        self.name = name

    def show_name(self):  # 如果是显示属性的值,一般用show_属性名
        print(self.name)


d = Dog()
print(d.get_name())
结果:
柯基

注意:没有return语句的方法或者函数,不要放到print里面,因为即使用print函数进行输出,结果也是None。

例如:

class Dog:
    def __init__(self, name="柯基"):
        self.name = name

    def get_name(self):  # 在设计类的时候,如果想通过方法得到一个属性的值,一般都是get_属性名
        return self.name  # !!

    def set_name(self, name):  # 如果想通过方法,设置一个属性的值话那就是,set_属性名(selg,形参)
        self.name = name

    def show_name(self):  # 如果是显示属性的值,一般用show_属性名
        print(self.name)


d = Dog()
print(d.show_name())  # 对象d先调用show_name()方法,然后再输出调用后的结果

结果:
柯基
None

解析:为什么会有None?首先,d.show_name()就是说对象调用show_name()这个方法,这个方法就会打印名字这个属性,然后就是控制台所看到的柯基。接着,调用完这个方法后,又用print函数进行输出,我们知道,在调用函数的时候,只有函数中有return时候,这个函数才会有返回值,而show_name()这个函数内部没有return,所以也就没有返回值,print时候也就只能显示None 。

再比如,设置下属性值,把狗的名字改成“柴犬”,然后再输出这个名字。

class Dog:
    def __init__(self, name="柯基"):
        self.name = name

    def get_name(self):  # 在设计类的时候,如果想通过方法得到一个属性的值,一般都是get_属性名
        return self.name  # !!

    def set_name(self, name):  # 如果想通过方法,设置一个属性的值话那就是,set_属性名(selg,形参)
        self.name = name

    def show_name(self):  # 如果是显示属性的值,一般用show_属性名
        print(self.name)


d1 = Dog()
d1.set_name("柴犬")
print(d1.get_name())

结果:
柴犬

练习:设计一个计算器类,实现基本的加减乘除功能。

class Calculator:  # 定义一个计算器类
    def __init__(self, operate="+"):
        self.operate = operate

    def calc(self, a, b):
        if self.operate == "+":
            return a + b

        elif self.operate == "-":
            return a - b
        elif self.operate == "*":
            return a * b
        elif self.operate == "/":
            if b != 0:
                return a / b
            else:
                return "除数为0了,不能进行除法运算"
        else:
            return "请重新输入一个运算符"


a = input("请输入一个运算符:")
num1 = int(input("请输入num1:"))
num2 = int(input("请输入num2:"))
c = Calculator(a)
print(c.calc(num1, num2))

结果:
请输入一个运算符:/
请输入num1:15
请输入num2:0
除数为0了,不能进行除法运算


请输入一个运算符:+
请输入num1:1
请输入num2:2
3

请输入一个运算符:-
请输入num1:1
请输入num2:2
-1


请输入一个运算符:*
请输入num1:3
请输入num2:5
15


注意:用a = input("请输入一个运算符:"),此时,init中 operate="+"这个默认值就没有用了。默认值的作用就是,当c = Calculator()时候,里面不放实参的时候会自动用默认值。
例如,不把a里输入东西
请输入一个运算符:
请输入num1:1
请输入num2:2
请重新输入一个运算符

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值