1、类的语法
# 类的语法
# 定义类
class Dog(object):
# 类的属性或者类变量,一般是公共属性,存在类的内存空间,所有实例对象共享
d_type = "京巴"
#初始化方法, 构造方法,实例化类的时候进行的初始化操作,这里定义的变量要实例属性
def __init__(self,name: str,age: int,):
print("初始化方法",name,age)
# 实例方法
def sayhi(self):
print("hello my name is dog,my type is {dt}".format(dt = self.d_type))
# 实例化类,生成类的对象
d1 = Dog("d1",2)
d2 = Dog("d2",3)
print(d1.d_type,id(d1.d_type))
print(d2.d_type,id(d2.d_type))
Dog.d_type = "藏獒"
print(d1.d_type,id(d1.d_type))
print(d2.d_type,id(d2.d_type))
d1.sayhi()
d2.sayhi()
2、实例方法的self到底是什么?
# 类的语法
# 定义类
class Dog(object):
# 类的属性或者类变量,一般是公共属性,存在类的内存空间,所有实例对象共享该内存空间
d_type = "京巴"
# 构造方法,实例化类的时候进行的初始化操作,这里的变量存在于对象的内存空间中,对象之间是隔离的
def __init__(self,name: str,age: int):
self.name = name
self.age = age
# 实例方法
def sayhi(self):
print("hello my name is dog,my type is {dt}".format(dt=self.d_type))
print("我的名字是{name},我的年龄是{age}".format(name = self.name,age = str(self.age)))
print(self) #我们通过打印的数值就知道self其实就是对象本身
d1 = Dog("name1",1)
d2 = Dog("name2",2)
d1.sayhi()
d2.sayhi()
print(d1)
3、类的属性
class Dog(object):
# 类的属性或者类变量,一般是公共属性,存在类的内存空间,所有实例对象共享该内存空间
d_type = "京巴"
# 构造方法,实例化类的时候进行的初始化操作,这里的变量存在于对象的内存空间中,对象之间是隔离的
def __init__(self,name: str,age: int):
self.name = name
self.age = age
d1 = Dog("d1",2)
d2 = Dog("d2",2)
# 两种方式可以调用类的属性,通过类和实例都可以调用
print(Dog.d_type)
print(d1.d_type)
d1.d_type = "藏獒"
print(d1.d_type) #相当于创建了一个实例变量
print(Dog.d_type) #当然不会影响这一部步骤的结果输出
print(d2.d_type) #当然不会影响这一步骤的结果输出,d2还是打印的类的属性的值
# 实例属性只能通过实例来调用
print(d1.age)
# 类不能调用实例属性
# print(Dog.name)
# 会抛错
4、类的继承
# 继承
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eate(self):
print("eating")
class Persion(Animal):
def __init__(self,name,age,address):
Animal.__init__(self,name,age) #执行父类的构造方法
self.address = address #执行子类的构造方法
# 子类可以自定义自己的方法,这个方法只能被这个子类和这个子类的子类实例调用
def talk(self):
print("talking")
# 子类当然可以重新父类的方法,子类如果调用eate方法,则优先调用自己重新的eate方法
def eate(self):
print("人在慢慢的吃饭")
class Dog(Animal):
def killrabbit(self):
print("killrabbit")
p1 = Persion("P1",23,"深圳")
p1.eate()
p1.talk()
d1 = Dog("d1",23)
d1.eate()
d1.killrabbit()
5、类的多继承
# 多继承
class Shenxian():
def __init__(self,name):
self.name = name
print("Shenxian的构造方法")
def fly(self):
print("Shenxian,fly")
def talk(self):
print("shenxian talk")
class Monkey():
def __init__(self,name,high):
self.name = name
self.high = high
print("monkey的构造方法")
def Monkey(self):
print("Monkey,Monkey")
def talk(self):
print("Monkey talk")
class King(Shenxian,Monkey):
def __init__(self,name,high,age):
Shenxian.__init__(self,name)
Monkey.__init__(self,name,high)
self.age = age
k1 = King("k1","dd","33")
k1.talk()
# 多继承的继承顺序
# 按顺序从左到右继承
# 广度优先(python2是深度优先)
6、类的封装
# 封装
# 防止该类的代码和变量被外部随意访问
class Persion(object):
def __init__(self,name):
self.name = name
self.__life = 100 #变量前面加2个下划线,外面就不能直接访问了,但是内部可以使用
def getlife(self): #可以通过方法来返回私有属性,让外部获取私有属性的值,但是不能修改
return self.__life
def __attck(self): #私有方法外部也不能访问
self.__life = self.__life - 10
def bite(self):
print(self.__life)
p1 = Persion("name")
# 如果外部想访问的话 可以这样搞
#
# 实例名._类名__方法名
r = p1._Persion__life
print(r)
7、类的多态
# 多态
# 一个对象会有多种表现形式,多个对象共用一个接口,又表现出不一样的形态
class Dog():
def sound(self):
print("汪汪汪")
class Cat():
def sound(self):
print("喵喵喵")
def make_sound(obj):
obj.sound()
d1 = Dog()
c1 = Cat()
# 同一个接口,不同的表现形式
make_sound(d1)
make_sound(c1)
8、classmethod装饰器
class Dog(object):
def __init__(self):
pass
@classmethod
#通过classmethod装饰器实现,被classmethod装饰后的方法称为类方法,类方法和普通方法
# 的区别在于类方法只能访问类变量,不能访问实例变量
def test(self):
#这个self其实是类本身,而不是具体的实例,我们通过打印可以知道
print(self)
d = Dog()
d.test()
# <class '__main__.Dog'>
print(Dog)
# <class '__main__.Dog'>
9、staticmethod装饰器
class Dog(object):
name = 1
def __init__(self):
pass
#通过staticmethod装饰器实现,被staticmethod装饰后的方法称为静态方法,静态方法和普通方法
# 的区别在于静态方法不能访问类的属性,也不能实例的属性
# 静态方法隔离了静态方法和类和实例的任何方法和属性
@staticmethod
def test():
print("123",Dog.name)
d = Dog()
d.test()
10、propty装饰器
class Dog(object):
name = 1
def __init__(self):
pass
# property把一个方法变成一个静态的属性
@property
def test(self):
if Dog.name == 1:
print("123",Dog.name)
else:
print("456", Dog.name)
@test.setter
def test(self,status):
pass
@test.deleter
def test(self):
pass
d1 = Dog()
d1.test
d2 = Dog()
Dog.name = 2
d2.test
# 被property装饰的方法只能这样当作一个变量去执行,不需要加括号,如果一个变量的值比较负责,有一些列的逻辑
# 被property装饰的方法只能这样当作一个变量去执行,虽然看起来是个变量,但是实际是不能赋值的
# d2.test = 2
# AttributeError: can't set attribute
# 如果想对一个方法做赋值,在需要使用 下面的方法
# 通过也可以实现删除
# 通过property把一个方法变成属性,通过@test.setter方法可以对test这个方法的进行赋值,通过@test.deleter
# 方法可以对test这个属性进行删除,此处的函数名称必须是一样的
@property
def test(self):
if Dog.name == 1:
print("123", Dog.name)
else:
print("456", Dog.name)
@test.setter
def test(self, status):
pass
@test.deleter
def test(self):
pass
11、反射
# 反射:可以通过字符串的形式来操作一个对象的属性
class Dog(object):
name = 1
def __init__(self,age,add):
self.age = age
self.add = add
def test(self):
pass
d = Dog(1,"深圳")
# hasattr 用于判断对象d是否有name这个属性
r1 = hasattr(d,"name")
r2 = hasattr(d,"age")
r3 = hasattr(d,"2b")
r4 = hasattr(d,"test")
print(r1,r2,r3,r4)
# getattr()用于获取对象d的name属性的值
print(getattr(d,"name"))
# setattr() 对对象的属性进行赋值
setattr(d,"age",3)
print(getattr(d,"age"))
# delattr 对对象的属性进行删除
delattr(d,"age")
print(hasattr(d,'age'))
12、动态加载模块
# 动态加载模块,热加载
import importlib
try:
obj = importlib.import_module("test5")
except ModuleNotFoundError as e:
print(e)
# 通过字符串的方式导入模块
13、类的双下划线方法
# 类的双下划线方法
class Dog(object):
def __init__(self,name):
self.name = name
def __len__(self):
print("执行len方法")
return 1
def __hash__(self):
print("执行hash方法")
return 1
def __eq__(self, other):
print("执行==方法")
return False
# 通过字典的方式获取值
def __getitem__(self, item):
print("执行d[key]")
return "__getitem__"
def __setitem__(self, key, value):
print("执行d[key] = value")
self.key = value
def __delitem__(self, key):
print("执行del d[key]")
def __delattr__(self, item):
print("执行del d.item的时候执行")
def __str__(self):
print("执行str(d1)的方法时候执行,或者直接打印对象的时候执行")
def __del__(self):
print(self.name,"对象销毁的时候执行,python的对象会自动化销毁的")
def __call__(self, *args, **kwargs):
print("对象后加括号执行的方法")
d1 = Dog("d1")
d2 = Dog("d2")
print(len(d1))
#就会执行实例的__len__方法
print(hash(d1))
#就会执行实例的__hash__方法
print(d1 == d2)
print(d1["name"])
d1["age"] = 10
print(d1["age"])
14、内置异常
# isinstance()
#
# issubclass()
# 内置异常
try:
pass
except ValueError as e:
print("传入一个调用者不期望的值")
except AttributeError as e:
print("试图访问一个对象没有的属性的错误")
except IOError as e:
print("输出输入错误,基本上无法打开文件")
except ImportError as e:
print("无法引入模块或者包")
except IndentationError as e:
print("代码没有正确对齐的错误")
except IndexError as e:
print("下标索引超出边界")
except KeyError as e:
print("试图访问字典中不存在的key值")
except KeyboardInterrupt as e:
print("ctrl + c被按下")
except NameError as e:
print("使用一个还未被赋予值的对象")
except SyntaxError as e:
print("python代码非法,可以认为是语法错误")
except TypeError as e:
print("传入对象和要求对象的类型不一致")
except FileNotFoundError as e:
print("文件不存在错误")
except Exception as e:
print("万能异常,但是只能抓内置的异常类型,自定义的异常这里是抓不到的")
else:
print("没有出异常会走到这里")
finally:
print("无论发生异常,还是没有发生异常,都要走到finally这里")
15、自定义异常
class MyException(BaseException):
def __init__(self,msg):
self.msg = msg
def __str__(self):
return self.msg
try:
for i in range(10):
if i == 9:
raise MyException("此时逻辑错误,捕获自定义异常")
else:
print(i)
except MyException as e:
print(e)
16、断言
assert type(1) is int
assert 1 == 2
assert 1 >= 2
# 断言也可以在函数中assert断言参数的类型是否符合我们的要求