python中实例化对象的通俗理解_如何最简单、通俗地理解Python的类?

目录:

一、笔记

二、我的自学路线

三、笔记目录

一、笔记

1) 类的构成

① 类由三个部分构成:1. 类名称:类型。

2. 类属性:对象的属性。

3. 类方法:对象的方法。

② 创建和使用类,类定义形式(代码):

class 类名:

属性列表:

方法列表:

③ 类是对象的类型,具有相同属性和行为事物的统称。类是抽象的,在使用的时候通常会找到这个类的一个具体存在。

# 定义类

class People:

# 类属性

sex = 'nan'

# 构造函数:魔术方法

def __init__(self,name,age):

# 实例化属性

self.name = name # self代表对象本身

self.age = age

# 实例化方法

def sleep(self):

self.aa = 1

print('{}正在睡觉,性别为{}'.format(self.name,People.sex))

def bb(self):

print(self.aa)

# 实例化对象

people1 = People('张三',21) # 属性赋予实例化对象

people1.sleep() # 调用实例化对象方法

print(people1.age) # 可以直接打印实例化对象的属性

'''

不报错

people1.bb() # 必须不先调用具有实例化属性的实例化对象方法

people1.sleep()

'''

'''

不报错

people1.sleep()

people1.bb()

'''

运行结果:

张三正在睡觉,性别为nan

21

'\n不报错\npeople1.sleep()\npeople1.bb()\n'

2) 类的属性

① 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。如果需要用在函数中使用 类名.类属性。

② 实例属性:定义在方法中的变量,只作用于当前实例的类。

③ __变量名 为私有属性,对象名._类名__私有属性 这样才能调用,否则不能调用。

④ 可以使用实例化对象名+.来访问对象的属性,也可以使用以下函数的方式来访问属性(反射)。1. getattr(obj,name[,default]):访问对象的属性。

2. hasattr(obj,name):检查是否存在一个属性。

3. setattr(obj,name,value):设置一个属性。如果属性不存在,会创建一个新属性。

4. delattr(obj,name):删除属性值,没有删除属性。

5. name 需要加单引号,obj为实例化对象名称。

⑤ __dict__:类的属性(包括一个字典,由类的属性名:值组成) 实现方式:实例化类名._dict_

⑥ __doc__:类的文档中的字符串 实现方式:(类名.)实例化类名._doc_

⑦ __name__:类名 实现方式:类名._name_

⑧ __bases__:类的所有父类构成元素(包含了一个由所有父类组成的元组)

⑨ 尽量把需要用户传入的属性作为实例属性,而把同类都一样的属性作为类属性。实例属性在每创造一个类是都会初始化一遍,不同的实例的实例属性可能不同,不同实例的类属性都相同。

10. 实例属性1. 在__init__(self,...)中初始化。

2. 内部调用时都需要加上self。

3. 外部调用时用"对象名.属性名"调用。

11. 类属性1. 类属性可以在__init__中修改。

2. 在内部用类名.类属性名调用。

3. 外部既可以用类名.类属性名又可以用instancename.类属性名调用。

12. 私有属性

1) 双下划线__开头:外部不可通过 "对象名.属性名" 来访问或者更改,实际将其转化为了"对象._类名__属性名"。

# coding=utf-8

class PeopleMan:

# 定义基本类属性

name = ''

age = 0

sex = 'woman'

# 定义私有属性,私有属性在类外部无法直接进行访问

__weight = 0

def __init__(self,n,a,w):

# 定义实例属性

self.name = n

self.age = a

self.__weight = w

def speak(self):

print("%s 说:我 %d 岁。" %(self.name,self.age))

# 实例化类

p = PeopleMan('runoob',10,30)

print(p._PeopleMan__weight) # 对象名._类名__私有属性 这样才能调用p.__weight,否则不能调用

# print(p.__weight) # 不能这样访问

p.speak()

运行结果:

30

runoob 说:我 10 岁。

# coding=utf-8

class PeopleMan:

# 定义基本类属性

name = ''

age = 0

sex = 'woman'

# 定义私有属性,私有属性在类外部无法直接进行访问

__weight = 0

def __init__(self,n,a,w):

# 定义实例属性

self.name = n

self.age = a

self.__weight = w

def speak(self):

print("%s 说:我 %d 岁。" %(self.name,self.age))

# 实例化类

p = PeopleMan('runoob',10,30) # p为实例化对象。

getattr(p,'sex') # 访问对象的属性。

运行结果:

'woman'

# coding=utf-8

class PeopleMan:

'''定义人类,其中有3个属性,两个方法'''

# 定义基本类属性

name = ''

age = 0

sex = 'woman'

# 定义私有属性,私有属性在类外部无法直接进行访问

__weight = 0

def __init__(self,n,a,w):

# 定义实例属性

self.name = n

self.age = a

self.__weight = w

def speak(self):

print("%s 说:我 %d 岁。" %(self.name,self.age))

# 实例化类

p = PeopleMan('runoob',10,30) # p为实例化对象。

getattr(p,'sex') # 访问对象的属性。

print(p.__dict__)

print(PeopleMan.__dict__)

print(p.__doc__) # 类文档中的字符串

print(PeopleMan.__doc__) # 类文档中的字符串

print(PeopleMan.__name__)

运行结果:

{'name': 'runoob', 'age': 10, '_PeopleMan__weight': 30}

{'__module__': '__main__', '__doc__': '定义人类,其中有3个属性,两个方法', 'name': '', 'age': 0, 'sex': 'woman', '_PeopleMan__weight': 0, '__init__': , 'speak': , '__dict__': , '__weakref__': }

定义人类,其中有3个属性,两个方法

定义人类,其中有3个属性,两个方法

PeopleMan

3) __init__()方法和self

① __init__()是一个特殊的方法属于类的专有方法,被称为类的构造函数或初始化方法,方法的前面和后面都有两个下划线。这是为了避免Python默认方法和普通方法发生名称的冲突。每当创建类的实例化对象的时候,__init()__方法都会默认被运行。作用就是初始化已实例化的对象。

② 在方法定义中,第一个参数self是必不可少的。类的方法和普通的函数区别就是self,self并不是Python的关键字,你完全可以用其他单词取代他,只是按照惯例和标准的规定,推荐使用self。

③ 在类中方法里面,不写__init__()构造方法,直接写实例化方法,或者实例化方法里面初始化实例化的方法的属性,当类比较小的时候,直接构造一个类,然后实例化方法通过实例化对象的参数传进去好像比较简单、快,并且不会报错,但是如果类里面的10个方法都需要10个相同参数,那要传10次,如果是通过构造方法,就第一次实例化对象的时候传入,后面通过self调用,工程庞大的话,用__init__()方法然后self调用更方便些,也规范些。

# coding=utf-8

class PeopleMan:

# 定义基本类属性

name = ''

age = 0

sex = 'woman'

# 定义私有属性,私有属性在类外部无法直接进行访问

__weight = 0

def __init__(self,n,a,w): # self换成其他,如r也行,但是方法里的self也要换成r

# 定义实例属性

self.name = n

self.age = a

self.__weight = w

def speak(self):

print("%s 说:我 %d 岁。" %(self.name,self.age))

# 实例化类

p = PeopleMan('runoob',10,30) # 创建实例化对象,p是实例化对象,默认运行__init__()

getattr(p,'sex') # 访问对象的属性。

运行结果:

'woman'

# coding=utf-8

class PeopleMan:

# 定义基本类属性

name = ''

age = 0

sex = 'woman'

# 定义私有属性,私有属性在类外部无法直接进行访问

__weight = 0

def __init__(r,n,a,w): # self换成r了

# 定义实例属性

r.name = n

r.age = a

r.__weight = w

def speak(self): # 这个self没有换,它和上面的r一样,都是实例化对象p

print("%s 说:我 %d 岁。" %(self.name,self.age))

# 实例化类

p = PeopleMan('runoob',10,30) # 创建实例化对象,p是实例化对象,默认运行__init__()

getattr(p,'sex') # 访问对象的属性。

运行结果:

'woman'

4) 类的三大特性

特性一:继承

① 现实生活中,继承一般指子女继承父辈的财产。程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中可以描述为猫和狗都继承自动物。同理,波斯猫和家猫都继承猫。而斑点狗,泰迪都继承之狗。程序中我们定义一个class的时候,可以从某个现有的class继承,新的class称之为子类(Subclass),而被继承的class称之为基类、父类或超类。子类继承其父类的所有属性和方法,同时还可以定义自己的属性和方法。

② 即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。如:一个Dog类型的对象派生自Animal类。

③ 可以多重继承,但是最好只写一个基类,需要注意圆括号基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,python从左至右搜索,即方法在子类中未找到时,从左到右查找基类中是否包含方法。

④ 继承会继承父类的所有属性,如果不想子类继承,就把属性设置为私有属性,父类的私有属性子类无法继承,但是可以访问。通常父类的基本属性对子类继承是没有影响的,通过实例化属性都是放在方法中的,子类可以通过方法重写来实现对继承的属性修改。

# 继承的形式

'''

class DerivedClassName(BaseClassName1,BaseClassName2,BaseClassName3):

.......

'''

# coding=utf-8

class PeopleMan:

# 定义基本类属性

name = ''

age = 0

sex = 'woman'

# 定义私有属性,私有属性在类外部无法直接进行访问

__weight = 0

def __init__(self,n,a,w):

# 定义实例属性

self.name = n

self.age = a

self.__weight = w

def speak(self):

print("%s 说:我 %d 岁。" %(self.name,self.age))

class speaker:

topic = ''

name = ''

def __init__(self,n,t):

self.name = n

self.topic = t

def speak(self):

print("我叫 %s:我是一个演说家,我演讲的主题是 %s"&(self.name,self.topic))

class student(PeopleMan,speaker): #student类拥有基类的属性和方法

grade = ''

def __init__(self,n,a,w,g,t):

# 调用父类的构造函数

PeopleMan.__init__(self,n,a,w) # 调用父类构造方法,或者super(student,self).__init__(n,a,w) 要先传入第一个基类的参数

speaker.__init__(self,n,t) # 和父类实例化属性保持一致 或者super(student,self).__init__(n,t)

self.grade = g

def speak(self): # 重写父类的方法,相当于对父类的方法重写定义了

print("%s 说:我 %d 岁了,我在读 %d年级"%(self.name,self.age,self.grade)) # 子类可以用父类的属性

s = student('ken',10,60,3,"Python")

s.speak() # 先找子类,子类没有则从左往右基类中找方法

运行结果:

ken 说:我 10 岁了,我在读 3年级

特征二:多态

① 它是指对不同类型的变量进行相同的操作,它会根据对象(或类)类型的不同而表现出不同的行为。

② 多态是指一类事物有多种形态,比如动物类,可以有猫,狗,猪等等。(一个抽象类有多个子类,因而多态的概念依赖于继承)

③ 多态与多态性是两种概念,多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。

④ 综合可以说,多态性是 : 一个接口,多种实现。

# 多态

import abc

class Animal(metaclass=abc.ABCMeta): #同一类事物:动物

@abc.abstractmethod

def talk(self):

pass

class Cat(Animal): #动物的形态之一:猫

def talk(self):

print('say miaomiao')

class Dog(Animal): #动物的形态之二:狗

def talk(self):

print('say wangwang')

class Pig(Animal): #动物的形态之三:猪

def talk(self):

print('say aoao')

# 多态性

import abc

class Animal(metaclass=abc.ABCMeta): #同一类事物:动物

@abc.abstractmethod

def talk(self):

pass

class Cat(Animal): #动物的形态之一:猫

def talk(self):

print('say miaomiao') # 多态性

class Dog(Animal): #动物的形态之二:狗

def talk(self):

print('say wangwang') # 多态性

class Pig(Animal): #动物的形态之三:猪

def talk(self):

print('say aoao') # 多态性

c = Cat()

d = Dog()

p = Pig()

def func(obj):

obj.talk()

func(c) # 一个接口,多种实现

func(d) # 一个接口,多种实现

func(p) # 一个接口,多种实现

运行结果:

say miaomiao

say wangwang

say aoao

特征三:封装性

① "封装"就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体(即类);封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员。

5) 类方法与静态方法

方法一:普通方法

① 外部通过实例化对象调用

def fun_name(self,...):

pass

方法二:静态方法

① 通过装饰器 @staticmethod 装饰

② 不能访问实例属性

③ 参数不能传入self

④ 与类相关但是不依赖类与实例的方法

⑤ 静态方法不需要接受参数,使用类名.类属性。

方法三:类方法

① @classmethod

② 不能访问实例属性

③ 参数必须传入cls(即代表了类对象--区别---self代表实例对象),并且用此来调用类属性:cls.类属性名

④ 静态方法和类方法都可以用类或者实例来调用,其两个的特点都是不能够调用实例属性。

class A:

# 基本类属性

d = 0

# 实例化方法

def foo(self,x):

print("executing foo(%s,%s)"%(self,x))

print("self:",self) # 打印self是什么

# 类方法

@classmethod

def class_foo(cls,x):

print("executing class_foo(%s,%s)"%(cls,x))

print('cls:',cls) # 打印cls是什么

print(cls.d) # cls为类,cls.d为类属性

# print(cls.n) 报错,因为n是实例的属性,不是类的属性

# 静态方法

@staticmethod

def static_foo(x):

print("executing static_foo(%s)"%x)

print(A.d) # 访问类属性,不能访问实例属性

a = A.foo('a','b') # self就是对象的一个属性,就是一个参数而已,因此不能打印self.x

运行结果:

executing foo(a,b)

self: a

# 实例化方法:

b = A() # 需要用实例化对象来调用它

b.foo('a') # 打印出来的self为实例化对象的地址

运行结果:

executing foo(<__main__.A object at 0x0000019E0EDBD2B0>,a)

self: <__main__.A object at 0x0000019E0EDBD2B0>

# 类方法:

# 方法一:通过类来调用

A.class_foo('a') # cls是一个类

运行结果:

executing class_foo(,a)

cls:

0

# 方法二:通过实例化对象来调用

b = A()

b.class_foo("a")

运行结果:

executing class_foo(,a)

cls:

0

# 静态方法:

# 静态方法不需要接受参数,使用类名.类属性

A.static_foo('a')

运行结果:

executing static_foo(a)

0

# 当把装饰器cls注释掉后,cls不是类,是实例化对象,相当于self

class A:

# 基本类属性

d = 0

# 实例化方法

def foo(self,x):

print("executing foo(%s,%s)"%(self,x))

print("self:",self) # 打印self是什么

# 类方法

# @classmethod

def class_foo(cls,x): # cls相当于self

print("executing class_foo(%s,%s)"%(cls,x))

print('cls:',cls)

print(cls.d) # d是类变量,类变量通常不作为实例变量使用。如果需要用在函数中使用 类名.类属性,这里用self. d可以运行,但是不规范

# 静态方法

@staticmethod

def static_foo(x):

print("executing static_foo(%s)"%x)

b = A()

b.class_foo("a")

运行结果:

executing class_foo(<__main__.A object at 0x0000019E0EE116A0>,a)

cls: <__main__.A object at 0x0000019E0EE116A0>

0

class A:

# 基本类属性

d = 0

def __init__(self,m,n):

self.m = m

self.n = n

# 实例化方法

def foo(self,x,y):

# 实例属性,不是只有写在init里面的是实例属性

self.y = y

print("executing foo(%s,%s)"%(self,x))

print("self:",self) # 打印self是什么

print(self.class_foo(self.m)) # 实例化对象b就相当于self,只不过self在里面访问,b在外面访问

print(self.class_foo(self.y)) # 会运行self.class_foo(self.y)函数,相当于b.class_foo(self.y)

print(x)

# print(self.class_foo(self.x)) # 如果前面不加 self.x = x 那么x就仅仅只是一个入口参数,不是实例化属性

def cal(self):

print(self.y) # 不报错,可以用上面一个实例方法里使用的self.y

# 类方法

@classmethod

def class_foo(cls,x):

print("executing class_foo(%s,%s)"%(cls,x))

print('cls:',cls) # 打印cls是什么

print(cls.d) # cls为类,cls.d为类属性

# print(cls.n) 报错,因为n是实例的属性,不是类的属性

# 静态方法

@staticmethod

def static_foo(x):

print("executing static_foo(%s)"%x)

b = A(10,2)

b.foo("a","y")

运行结果:

executing foo(<__main__.A object at 0x0000019E0EDBDC40>,a)

self: <__main__.A object at 0x0000019E0EDBDC40>

executing class_foo(,10)

cls:

0

None

executing class_foo(,y)

cls:

0

None

a

class Parent: # 定义父类

def myMethod(self):

print('调用父类方法')

class Child(Parent): # 定义子类

def myMethod(self):

print('调用子类方法')

c = Child() # 子类实例

c.myMethod() # 子类调用重写方法

super(Child,c).myMethod() # 用子类对象调用父类已被覆盖的方法

运行结果:

调用子类方法

调用父类方法

6) 方法重写

① 避免用下划线作为变量名的开始,因为下划线对解释器有特殊的意义。

② 双下划线 变量名 双下划线:定义的是特殊方法,类似__init__()之类的。

③ 单下划线 变量名:"单下划线" 开始的成员变量叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量。以单下划线开头的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用“from xxx import *”而导入。

④ 双下划线 变量名:"双下划线" 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

7) 相关定义

① 类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例,类是对象的类型。类是抽象的概念,而对象是一个你能够摸得着,看得到的实体。两者相辅相成,谁也离不开谁。

② 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

③ 数据成员:类变量或者实例变量,用于处理类及其实例对象的相关的数据。

④ 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫覆盖(override),也称为方法的重写。

⑤ 局部变量:定义在方法中的变量,只作用于当前实例的类。

⑥ 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。

⑦ 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)

⑧ 实例化:创建一个类的实例,类的具体对象。

⑨ 方法:类中定义的函数。

⑩ 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

二、我的自学路线

01 安装Python编辑器 [ 已整理 ]

02 Python编译器快捷键 [ 已整理 ]

03 Python基础 [ 已整理 ]

04 Python难点 [ 整理ing ]

05 Python常用的库 [ 整理ing ]

06 爬虫 [ 看视频ing ]

三、笔记目录

( ……更多笔记,见专栏 )

"♥我的笔记,希望对你有帮助♥"

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值