目录:
一、笔记
二、我的自学路线
三、笔记目录
一、笔记
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 ]
三、笔记目录
( ……更多笔记,见专栏 )
"♥我的笔记,希望对你有帮助♥"