class A():
name = "changsha" # 静态属性,类属性
def __init__(self):
self.country="china" # 普通属性,实例属性
#普通(实例)方法
#接收的第一个参数,就代表实例本身
def normal_method(self,name):
pass
# 类方法, 使用classmethod.装饰的方法,称为类方法
# 接收的第一个参数是类
@classmethod
def class_method(cls,name):
pass
# 静态方法, 使用staticmethod装饰的方法,不装饰的话实例调用该方法时默认会传递实例对象给方法的,这样就会报错
# 可以接收参数也可以不接受参数,参数不代表实例也不代表类
@staticmethod
def static_method(name):
pass
实例可以调用三种方法,用类去调用实例方法时需手动传入一个实例
class test:
name = ""
_name = "" # 保护属性
__name = "" # 私有属性
def _func(self): # 保护方法
pass
def __func(self): # 私有方法
pass
对于保护属性和方法,使用起来与普通属性和方法没有区别,只是在使用import * 时不能被导入
对于私有属性和方法,其实是伪私有。不过是将双下划线的属性或方法改了一个名字为: _类__标识名
class test:
__name = "私有属性" # 私有属性
def __func(self): # 私有方法
print("私有方法")
t = test()
print(t._test__name) # 通过这样的格式即可调用
t._test__func()
所有以双下划线开头和结尾的方法,统称为魔术方法(magic method)
这种魔术方法不需要调用,在特定场景下自动执行。
由于markdown格式下对下划线做纠正太麻烦了,所以下面有的地方可能格式有些不正确,但能明白我指的是那个方法就行
• new:创建实例
• init:初始化实例
在实例释放、销毁的时候自动执行的,通常用于做一些收尾工作, 如关闭一些数据库连接,关闭打开的临时文件等
class a:
def __del__(self):
print("del")
a1 = a()
del a1 # 此时就会自动调用del方法,不手动del时,等程序执行结束时也会自动执行del方法
把类实例化后的对象当做函数来调用的时候自动被调用
class a:
def __call__(self):
print("call")
a1 = a()
a1() # 此时就会执行call方法,像函数、类都是通过call方法来实现的
有str方法时使用str方法,没有就使用repr方法
class A():
def __str__(self):
return "str...A"
def __repr__(self):
return "repr...A"
a = A()
print(a) # print一个实例时就是调用str方法
str_a = str(a) # 使用str()函数时也是调用实例中的str方法
# 当在交互式命令行中输入a之后回车,就会调用repr方法输出内容
使类的实例能够像字典一样被使用,适合用来进行配置
class A():
def __init__(self):
self.data = {} # 初始化个空字典
def __getitem__(self, key):
return self.data.get(key, 0) # key存在返回value,不存在返回0
def __setitem__(self, key, value):
self.data[key] = value
def __delitem__(self, key):
del(self.data[key])
a = A()
a["name"] = "sc" # 此时调用setitem方法,name传给key,sc传给value
print(a["name"]) # 此时调用getitem方法
del a["name"] # 调用delitem方法
自定义 加法 和 大于方法
class A:
def __init__(self,num):
self.time = time.time()
self.num = num
def __add__(self,x):
print("this is add")
return self.num + x
def __gt__(self,other):
print("this is gt")
return self.time > other.time # 根据创建的时间戳来比大小,越新创建的越大
a1 = A(5)
b = a1 + 3 # 调用add方法
print("b is :"b)
a2 = A(4)
print(a1>a2) # 调用gt方法
使用with语句管理的对象 称为 上下文管理器对象
都会实现enter、exit魔术方法
enter做一些初始化工作
exit做一些结束收尾工作,释放资源
__dict__:类的属性(包含一个字典,由类的数据属性组成)
__doc__:类的文档字符串
__name__:类名
__module__:类定义所在的模块
__bases__:类的所有父类构成元素
__class__:类型,比如类就返回type,实例就返回它的父类
对某一个对象属性(方法)的增删改查
#python自省
print(hasattr(math,"xx")) #判断math有没有xx属性
print(setattr(math,"xx",1)) #设置math的xx属性为1
print(getattr(math,"xx") #获取math的xx属性
print(delattr(math,"xx")) #删除math的xx属性
def func2():
pass
setattr(a,"func",func2) # 将func2方法添加到a实例中并命名为func
创建类的类称之为元类
一些基本类的元类都是type
print(str.__class__) # 输出:
>>> print(object.__class__) # object是所有类的父类,这是从继承的角度
<class 'type'> # type是创建类中最顶层的类,这是从实例和类的角度
# 两者的关系很难说,type继承了object,但object又由type创建
可以自定义一个元类
class MyMate(type): # 继承type类
#拦截类的创建
# 名字 继承(元组) 方法属性(dict)
def __new__(cls,name,bases,attrs):
attrs["test"] = "mymate test"
print(name,bases,attrs)
return type.__new__(cls,name,bases,attrs)
class A(metaclass=MyMate):
pass
a = A()
print(a.test)
抽象基类 定义了接口规范,子类必须实现父类里面的抽象方法
抽象类不能实例化
想定义抽象基类,需要先导入ABC模块:
from abc import ABC, abstractmethod
ABC模块提供了一种定义抽象基类的方式,是指"Abstract Base Classes"(抽象基类)模块。它是Python标准库中的一个模块,位于
abc
包中。
from abc import ABC,abstractmethod
#抽象基类
class A(ABC):
@abstractmethod # 被这个装饰的方法称为抽象方法
def eat(self):
pass
def drink(self): # 没有被@abstractmethod装饰的方法为普通方法
pass
class B(A): # 子类必须实现父类中的抽象方法
def eat(self):
print("this is eat")
b = B()