定义:
- 一群具有相同特征或行为的事物的统称;
- 是方法和属性的封装(集合);
- 进入类定义时,就会创建一个新的命名空间,并把它用作局部作用域。因此,所有对局部变量的赋值都是在这个新命名空间内进行的。特别的,函数定义会绑定到这个局部作用域里的新函数名称
- 在python中定义中,其名称首字母大写。
类中包含的属性和方法
类属性/类方法:
类名下方使用赋值语句定义,通常用来记录与这个类相关的特征;
该类所有对象共享,在内存中只保存一份;
通过类名直接访问【类名.属性名/方法名】
实例属性/方法:
实例属性在每一个对象中都保存一份,实例方法在内存中只保存一份
通过对象名访问【对象名.属性名/方法名】
一个对象的属性可以是另一个类创建的对象;定义属性时如果不知道设什么初始值,可以设为None;
私有类型属性/方法
对象中某些属性只希望在内部被使用,不希望外部被访问到【即不能通过对象.属性/方法进行访问】,子类也访问不到。
在属性/方法前增加2个下划线定义的就是私有属性/方法.如self.__age
dir内置函数:dir(对象/标识符)可以查看对象内部所有的属性和方法
保护类型属性/方法
单下划线开头的变量或方法,只允许其自身和子类访问
不能通过from module import * 进行导入
类中的方法实际上就是一个稍微特殊点的函数(方法的第一个参数必须为self);方法的调用需要绑定到特定的对象上(通过self.或实例对象名),而函数不需要
子类与父类
子类访问父类属性或方法时,需要将父类导入该模块中,否则创建的子类对象将出错
Super(子类名【当前类】,self).__ init __():对继承的父类属性进行初始化。
【父类名. __ init __(self,参数)也可以实现父类属性的初始化,二者在单继承时区别不大,但在多继承时该方法会浪费资源】
如果子类继承父类时不做初始化,子类会自动继承父类属性;
如果子类继承父类时做了初始化,但没有调用super方法初始化父类的构造函数,则不会继承父类的属性
如果子类继承父类时做了初始化,且调用了super方法初始化父类的构造函数,则子类会继承父类的属性
子类重写父类方法有2种情况
- 覆盖父类方法(多态)
- 对父类方法进行拓展(继承):父类原本封装的方法是子类方法的一部分;
实现步骤:
1.子类重写父类方法
2.在需要位置使用super父类方法的执行代码
3.其它位置针对特定要求编写相应的拓展代码
魔法方法
python中前后双下滑线定义出来的方法,供自己调用的。这些方法会在特定的条件下被触发执行
__ new __():
创建和返回一个新对象的方法,用来控制一个新实例的生成过程
在内存中为对象分配内存空间;返回对象的引用。
对象创建时最先调用的方法,优于 __ init ()方法执行; init __()方法则是在对象创建完后添加一些属性的方法
class Foo():
def __new__(cls,*args,**kwargs):
return object.__new__(cls,*args,**kwargs)
#cls指的是当前类,如果传入别的类,则返回别的类对象
#args kwargs后续将传入到__init__中进行初始化
#new方法必须有返回值,才会执行相应的init方法,返回值正是其中的self
作用:
控制实例化过程
实现单例
def __new__(cls,value):
return Super().__new__(cls,abs(value))
#abs会将传如到init中的值提前进行处理
__ init __():
初始化(构造)函数,用于进行一些初始化工作
__ del __():
析构函数,对象销毁前自动调用,该方法调用,表示生命周期结束。
__ getitem __():
将类变成一个序列,可实现切片和遍历操作,其生成的对象具备迭代功能(成为一个可迭代对象)
当实例对象做P【】运算或使用for循环遍历实例对象时会自动调用该方法对对象的属性进行访问
在使用for … in …迭代对象时,如果对象中没有实现__iter __, __next __迭代器协议,python解释器就会寻找 __ getitem __来迭代对象,如果连该方法都没有定义,解释器就会报错。
__ call__():
允许一个类的实例对象能够像函数那样被调用;如果类中实现了该方法,那么实例对象将成为一个可调用对象【可以将( )应用到自身并执行,一般有函数、类等】
object = Testcall("name")
object() 《------》 object.__call__()
__dict __():
查看类(实例对象)内部所有属性名和属性值组成的字典
对于类名调用print(类名. __ dict __)只返回自身的属性,与父类、子类无关
对于实例对象调用,可以使用字典方式对其属性值进行修改,如:对象. __dict __[name]=“a”
__ dir__():
查看对象拥有的所有属性和方法
print(对象.__dir__())
print(dir(对象)
__len __ ():
查看对象(序列)的长度【即元素的个数】
同时实现了 __ getitem __和 __ len __方法,则可认为是一个序列
__ repr__():
print(对象)时,自定义输出的内容,该方法必须返回一个字符串
其它常用的函数/方法
判断类中有无属性或者方法的三大方法: hasattr getattr setattr
先申明类不能拥有实例的属性,但实例可以使用类的属性和方法
类方法/静态方法/特殊方法
1.类方法 @classmethod
如果要对类中的属性方法直接操作,又与实例化对象无关时,可以用到类方法。原则上,类方法是将类本身作为对象进行操作的方法
类方法是通过类名直接调用的方法,类方法至少要有一个参数,第一个默认是 cls
class A:
name = "barry"
def func(self):
print(self)
@classmethod
def func2(cls):
# 这里的 cls 指的就是类本身
# 而上面的 self 指的是实例化对象
print(cls)
print(777)
a = A()
# 实例化对象调用类的普通方法
a.func()
# 运行结果:
<__main__.A object at 0x7f310784d3c8>
2.静态方法 @staticmethod
静态方法是类中的函数,不需要实例。主要用来存放逻辑性的代码,逻辑上属于类,但和类本身没有关系
静态方法中不会涉及类和实例化对象的任何属性和方法
class A:
name = "barry"
@staticmethod
def func():
print(666)
a = A()
A.func() # 666
a.func() # 666
3.类的特殊方法 @property
将一个方法伪装成属性,逻辑没变,就只是看起来更合理
class A:
def __init__(self, username, password):
self.__username = username
self.__password = password
@property
def name(self):
return self.__username
a1 = A("Jane", 123)
print(a1.name) # Jane
其它常用的函数
1.hasattr()函数
用于判断某个实例对象是否包含指定名称的属性或方法
hasattr(obj.name)
out:
True / False
2.getattr()函数
获取某个实例对象指定的属性/方法
getattr(obj,name[,default])
若输入的name为属性则返回相应的值;若为方法名,则返回该方法状态信息
若查找失败,则返回默认参数default,若没有设置default,程序将报错
如果给定的属性name是对象的方法,则返回的是函数对象。需要注意的是,如果给定的方法func()是实例函数,则不能写getattr(A, ‘func’)(),因为fun()是实例函数的话,是不能用A类对象来调用的,应该写成getattr(A(), ‘func’)();
3.setattr()函数
修改或添加相应的属性/方法
setattr(obj.name,value)
若本身存在则进行修改,若不存在就添加
4.issubclass(cls, class_or_tuple)函数
检查类(cls)是否为后类或元组包含的多个类中的任意子类
issubclass(str, (list,tuple))
issubclass(str,object)
out:
False
True
5.isinstance(obj,class_or_tuple)
检查obj是否为后一类或元组包含的多个类中容易类的对象,返回值是一个bool类型。
isinstance([10],(list,tuple))
isinstance("hello",str)
out:
True
True
参考链接:
1.https://blog.csdn.net/qq_39314932/article/details/80716295