定义类
# 定义类->自定义类(由程序员创建的类) # python创建的list类 # class list(object): # 开发 王者荣耀 ,我想创建一个悟空(对象)->类(英雄类)->类型(Hero) # 自定义类 # class 标识这一个类 # 三种类的的创建方式都是在python2.x产生的 # object 是所有类的父类 # 02 是后期产生的 # 01 02 叫经典类,它们都是没有父类(基类)的 # 03 叫新式类 # 在python3.x中 无论写01 02 03哪种方式,都是继承object类 # 但是在python2.x中它是区分01 02 相同,而03是有父类的 # 01 class Hero: pass # 02 class Hero(): pass # 03 class Hero(object): pass
创建对象
# 自定义一个悟空英雄对象 # 自定义一个英雄类 # 自定义类名 一般遵循的是大驼峰 class Hero(object): # 定义一个方法(实例方法、或者对象方法) # 实例方法的第一个参数self # 实例方法 下划线或者小驼峰(公司要求) def move(self): print("英雄会走") # 使用自定义类创建一个对象 wukong = Hero() # 调用英雄类中的方法(想要使用其类中的方法,要使用这个类创建一个对象,使用对象调用其类里面的方法) wukong.move()
添加和获取对象属性
# 自定义一个悟空对象 # 他会走(方法和行为,他有名字:悟空,年龄500,血量3000,攻击力400(属性和特征)) # 自定义一个英雄类 class Hero(object): # 方法(实例 或者 对象) def move(self): # self是谁,哪个对象调了这个方法,self就是那个对象 print(id(self)) print("英雄会走") # 无论使用对象调用其类的方法或是属性,都是使用“点”语法 # 使用类创建对象 wukong = Hero() # 执行下对象方法 wukong.move() # 给对象添加属性 # 名字 wukong.name= "悟空" # 年龄 wukong.age = 500 # 血量 wukong.hp = 3000 # 攻击力 wukong.atk = 400 # 获取对象身上的属性 print(wukong.name, wukong.age, wukong.hp, wukong.atk) # 什么时候才可以给对象添加属性? # 先要有对象才可以给这个对象添加属性 # 如何查看一个类创建的多个对象,是否是一个对象呢? # print(wukong) # <__main__.Hero object at 0x00000252E13A0780> ->16进制 # 保存到内侧中,需要开辟内存空间(底层是二进制(0,1)) # 创建 猪八戒 # zhubajie = Hero() # print(zhubajie) # 如果想查看10进制 print(id(wukong)) # print(id(zhubajie)) # 在类的外面使用的是对象名 # 在类的方法里面使用的是self # 对象名 和self 本身就是一个人 # 了解 逢x进1 # 二进制 0 1 # 十进制 0 1 2 ... 9 # 16进制 0 1 2 ... ABCDEF
在方法类通过self获取获取属性
#自定义一个狗类,来创建各种名字叫旺财的狗,年龄5 皮色 黑色,会吃骨头 # 自定义一个类 class Dog(object): # 方法 def eat(self): print("狗吃骨头") # 自定义一个方法,完成打印对象属性 def info(self): print(self.name, self.age, self.color) # 自定义一个旺财对象 wangcai = Dog() wangcai.eat() # 给对象添加属性 wangcai.name = "旺财" wangcai.age = 5 wangcai.color = "黑色" # 获取对象属性 # print(wangcai.name, wangcai.age, wangcai.color) # 使用对象名调用类中的对象方法 wangcai.info() # 在类的外面使用,使用的是对象名.属性名 # 在类的实例方法内部,使用的是self.属性名(self == 调用这个方法的对象)
__init__方法
# 自定义一个狗类 class Dog(object): # 构造方法 # 在python中使用_开头,并以_结尾的称之为魔法方法 # 魔法方法是python提供给我们的 # object的提供的魔法方法 # 在特殊的情况下(python可以监听到你使用自己的类创建一个对象),被python执行 # 在自定义类(程序员自己写的类)中实现(重写)魔法方法,做自己特有的事情 # 注意:当走进_init_方法的时候,对象已经创建成功 def __init__(self): print("_init_") # 给对象的属性赋值 self.name = "旺财" self.age = 5 self.color = "灰色" # 会吃骨头 def eat(self): print("会吃骨头") # 定义一个方法 def info(self): print("名字:%s"% self.name) print("年龄:%s" % self.age) print("毛色:%s" % self.color) print("="*30) # 通过自定义的类创建狗 -> 对象 # 特征,叫的名字都是旺财,年龄都是5岁,毛色都是灰色 wangcai1 = Dog() # input("到了吗") # 添加属性 # wangcai1.name = "旺财" # wangcai1.age = 5 # wangcai1.color = "灰色" # 调用对象方法 wangcai1.info() wangcai2 = Dog() # 添加属性 # wangcai2.name = "旺财" # wangcai2.age = 5 # wangcai2.color = "灰色" # # 调用对象方法 wangcai2.info() wangcai3 = Dog() # 添加属性 # wangcai3.name = "旺财" # wangcai3.age = 5 # wangcai3.color = "灰色" # 调用对象方法 wangcai3.info()
有参数的__init__方法
# 自定义一个狗类 class Dog(object): # 构造方法 def __init__(self, new_name, new_age, new_color="白色"): # 给对象的属性赋值 self.name = new_name self.age = new_age self.color = new_color # 会吃骨头 def eat(self): print("会吃骨头") # 定义一个方法 def info(self): print("名字:%s"% self.name) print("年龄:%s" % self.age) print("毛色:%s" % self.color) print("="*30) # 创建旺财 wangcai = Dog("旺财", 5) wangcai.info() # 创建斗牛犬 douniu = Dog("斗牛犬", 4) douniu.info()
__str__()方法
# 自定义一个英雄类 class Hero(object): # 构造方法 def __init__(self, name, hp, atk): # 设置属性的值 self.name = name self.hp = hp self.atk = atk # 打印信息 # def info(self): # print(self.name, self.hp, self.atk) # 实现下父类已有的魔法方法 # 不可以添加参数(形参) # 会返回一个字符串 # 追踪对象属性信息变化 def __str__(self): return "名字:%s 血量:%d 攻击力:%d" % (self.name, self.hp, self.atk) # 悟空 wukong = Hero("悟空", 4000, 400) # wukong.info() # 默认情况下 打印的是对象的16进制地址 # 如果类中实现了__str__方法 如果打印对象名 会输出的是__str__方法中的返回值(字符串) print(wukong) # __str__一般用于程序员开发调试代码
__del__()方法
# 自定义一个英雄类 class Hero(object): # 构造方法 def __init__(self, name): # 设置属性值 self.name = name # 输出一个字符串(追踪对象属性信息变化) def __str__(self): return "名字:%s" % self.name # 监听对象销毁会走的方法 def __del__(self): print("再见") # 创一个对象 # gailun = Hero("盖伦") # 程序员杀死对象 # del gailun # input("停在这里") # python中是自动内存管理 # 创一个对象 gailun = Hero("盖伦") gailun1 = gailun gailun2 = gailun # 引用计数问题 del gailun del gailun1 del gailun2 input("停在这里") # python中是自动内存管理
单继承
# 自定义一个师傅类 class Master(object): # 构造方法 def __init__(self): self.kongfu = "古法煎饼果子配方" # 擅长做煎饼果子 def make_cake(self): print("按照<%s>制造煎饼果子" % self.kongfu) # 创建一个李师傅 对象 lishifu = Master() print(lishifu.kongfu) lishifu.make_cake() # 自定义一个徒弟类 # 子类继承了父类,就拥有了父类的"方法"和"属性" # 子类拥有了父类的属性,是因为子类使用了父类的__init__(对属性赋值的地方) class Prentice(Master): pass # 自定义一个大猫 damao = Master() print(damao.kongfu) damao.make_cake()
多继承
# 自定义一个师傅类-(古法) class Master(object): # 构造方法 def __init__(self): self.kongfu = "古法煎饼果子配方" # 擅长做煎饼果子 def make_cake(self): print("按照<%s>制造煎饼果子" % self.kongfu) # 大烟袋 def dayandai(self): print("大烟袋") # 自定义一个新东方-(现代) class School(object): # 构造方法 def __init__(self): self.kongfu = "现代古法煎饼果子配方" # 擅长做煎饼果子 def make_cake(self): print("按照<%s>制造煎饼果子" % self.kongfu) # 小烟袋 def xiaoyandai(self): print("小烟袋") # 自定义一个徒弟类 # (School, Master)哪个类在这最前面就执行该类的方法 class Prentice(Master, School): pass # 自定义一个大猫 damao = Prentice() # 为什么会打印的第一个父类的属性->古法煎饼果子配方? # 如果两个父类的方法名(__init__)相同 print(damao.kongfu) # 如果两个父类的方法名相同,子类会执行第一个父类 damao.make_cake() # 如果两个父类的方法名相同。子类会分别执行 damao.dayandai() damao.xiaoyandai()
子类重写父类的同名属性和方法
# 自定义一个师傅类-(古法) class Master(object): # 构造方法 def __init__(self): self.kongfu = "古法煎饼果子配方" # 擅长做煎饼果子 def make_cake(self): print("按照<%s>制造煎饼果子" % self.kongfu) # 自定义一个新东方-(现代) class School(object): # 构造方法 def __init__(self): self.kongfu = "现代古法煎饼果子配方" # 擅长做煎饼果子 def make_cake(self): print("按照<%s>制造煎饼果子" % self.kongfu) # 自定义一个徒弟类 # (School, Master)哪个类在这最前面就执行该类的方法 class Prentice(Master, School): # pass # 构造函数 def __init__(self): self.kongfu = "猫式煎饼果子配方" # 擅长做煎饼果子 # 子类继承了父类,子类重写父类已有的方法 # 重写:子类继承父类,做自己特有的事情 def make_cake(self): print("按照<%s>制作煎饼果子" % self.kongfu) # 自定义对象 大猫 # 如果子类的方法名(子类已经重写父类的方法)和父类相同的时候,默认会使用子类的方法 # 为什么会使用子类的属性(kongfu),子类重写了父类已有的__init__方法 damao = Prentice() damao.make_cake()
子类调用父类的同名属性和方法
# 自定义师傅类-古法 class Master(object): # 方法 def make_cake(self): print("古法煎饼果子") # 自定义师傅类-现代 class School(object): # 方法 def make_cake(self): print("现代煎饼果子") # 自定义一个徒弟类 class Prentice(Master, School): # 方法 def make_cake(self): print("猫式煎饼果子") # 古法 def old_cake(self): # 如果子类重写了父类已有的方法 # 但是子类还想用父类的同名方法 # 解决方案:父类名.对象方法名(self) Master.make_cake(self) # 现代 def new_cake(self): # 同上 School.make_cake(self) # 自定义一个对象 大猫 damao = Prentice() # 猫式 damao.make_cake() # 古法 damao.old_cake() # 现代 damao.new_cake()
super()的使用
# 自定义师傅类-古法 class Master(object): # 方法 def make_cake(self): print("古法煎饼果子") # 自定义师傅类-现代 class School(object): # 方法 def make_cake(self): print("现代煎饼果子") # 自定义一个徒弟类 class Prentice(Master, School): # 方法 def make_cake(self): print("猫式煎饼果子") Master.make_cake(self) School.make_cake(self) # 古法 def old_cake(self): # 01方式(单和多继承都适用) # Master.make_cake(self) # super默认会调用第一个父类的方法(适用于单继承或只想使用第一个父类的方法) # 02方式 ,适用于新式类 # 格式:super(子类类名,self).父类方法名() # super(Prentice, self).make_cake() # 03方式(适用于新式类),是02方式的简写 super().make_cake() # 现代 def new_cake(self): # School.make_cake(self) super().make_cake() # 自定义一个对象 大猫 damao = Prentice() # 猫式 damao.make_cake() # 古法 # damao.old_cake() # 现代 # damao.new_cake()
私有属性和私有方法
# 自定义一个师傅类 class Master(object): # 构造方法 def __init__(self): # 配方 self.kongfu = "古法配方" # 添加一个属性 # 如果一个属性的名字开头是两个下划线,就代表这个属性私有 self.__money = 10000 # 制造煎饼果子 def make_cake(self): print("古法煎饼果子赚了%d元" % self.__money) # 在类的里面是可以使用的 # print(self.__money) # self.__hellop__ython() # 私有的实例方法 # 私有的作用:高大尚 def __hellop__ython(self): print("我爱python") # 自定义一个对象 lishifu = Master() print(lishifu.kongfu) # 如果一个属性私有后,就不能使用对象调用这个属性(类的外面使用) # print(lishifu.__money) lishifu.make_cake() # lishifu.__hellop__ython() # 自定义一个师傅类 class Master(object): # 构造方法 def __init__(self): # 配方 self.kongfu = "古法配方" # 添加一个属性 # 如果一个属性的名字开头是两个下划线,就代表这个属性私有 self.__money = 10000 # 制造煎饼果子 def make_cake(self): print("古法煎饼果子") # 私有的实例方法 # 私有的作用:高大尚 def __hellop__ython(self): print("我爱python") # 自定义一个类 ,继承师傅类 class Prentice(Master): pass damao = Prentice() print(damao.kongfu) damao.make_cake() # 子类继承了父类,如果父类额属性或者方法私有后,将不会被继承
修改私有属性值
# 自定义一个人类 class Person(object): def __init__(self): self.name = "小明" self.age = 20 # 定义一个方法(获取属性的值,一般方法名使用get) def get_age(self): return self.__age # 定义一个方法(对属性赋值的时候,一般方法名中使用set) def set_age(self, new_age): self.__age = new_age # 间接的修改私有属性的值,和获取私有属性的值 # 对象 xiaoming = Person() # print(xiaoming.name) # 01 使用对象调用私有属性,完成打印age的值 print(xiaoming.get_age()) # 02 使用对象设置私有属性的值 xiaoming.set_age(30) # 测试 print(xiaoming.get_age())
类属性和实例属性
# 自定义一个类 class Person(object): # 国家 country = "中国" def __init__(self, name, age): # 实例属性(对象属性) self.name = name self.age = age # xiaoming = Person("小明", 20) # # 使用实例属性: 对象名.实例属性名 # print(xiaoming.name) # 修改实例属性: 对象名.实例属性名 = 值 # xiaoming.name = "小明明" # print(xiaoming.name) # 使用类属性 # 01: 类名.类属性名 # print(Person.country) # 02: 对象名.类属性名 # xiaoming = Person("小明", 20) # print(xiaoming.country) # 修改类属性 # 01: 类名.类属性名 = 值 # Person.country = "中华" # print(Person.country) # 02: 不存在(对象名.类属性名 = 值) # xiaoming = Person("小明", 20) # # python认为你是给对象设置实例属性(只是和类属性名相同而已) # xiaoming.country = "中华" # print(xiaoming.country) # print(Person.country) # 关于类属性 内存问题 # xiaoming1 = Person("小明1", 20) # xiaoming2 = Person("小明2", 20) # 类属性python只会开辟一份内存(他是代表这个类的属性这个类python中只有一个) # print(id(xiaoming1.country)) # print(id(xiaoming2.country)) # print(id(Person.country)) # 类属性好处??? # 为了节约内存 # 为了后期业务需求更改 可以提高开发效率 # 自定义一个类 class Person(object): # 国家 # country = "中国" def __init__(self, name, age, country): # 实例属性(对象属性) self.name = name self.age = age self.country = country
类方法
# 自定义一个类 class Person(object): # 类属性(私有) __country = "中国" # 定义类方法 # 获取私有类属性的值 # cls = 类名 # 修饰器 @classmethod def get_country(cls): return cls.__country # 修改私有类属性的值 @classmethod def set_county(cls, new_county): cls.__country = new_county # 01:类名.类方法(调用类方法) # print(Person.get_country()) # Person.set_county("中华") # print(Person.get_country()) # 02:对象名.类方法(调用方法) xiaoming = Person() # 调用类方法 print(xiaoming.get_country()) xiaoming.set_county("中华") print(xiaoming.get_country())
静态方法
# 值自定义类 class Person(object): # 私有类的属性(国籍) __country = "中国" # 构造方法 def __init__(self): self.name = "小明" # 私有 self.__age = 20 # 实例方法(对象方法)获取私有属性 def get_age(self): return self.__age # 实例方法(对象方法)修改私有属性 def set_age(self, new_age): self.__age = new_age #类方法 @classmethod def get_country(cls): return cls.__country # 类方法 # 修改类方法 @classmethod def set_country(cls, new_country): cls.get_country = new_country # 静态方法 @staticmethod def hello(): print("今天天气不错") # 使用静态方法 # 01:类名.静态方法名 # Person.hello() ''' python中类中的方法总结: - 实例方法(对象方法) -> 场景最多 - 定义格式:def 实例方法名(self): - 调用格式:对象名.实例方法名() - 使用场景:在方法中需要self - 类方法 -> 对私有属性取值或者赋值 - 定义格式:@classmethod def 类方法名(cls): - 调用格式:类名.类方法名() 或者 对象名.类方法名() - 使用场景:在方法中需要cls(类名) - 静态方法 -> 一般不用 -定义格式:@staticmethod def 静态方法名(): - 调用格式:类名.类方法名() 或者 对象名.类方法名() - 使用场景:在方法中不需要self,也不需要cls '''
__new__()方法
# 自定义一个人类 class Person(object): # 监听python使用其类创建对象,并返回对象 -> __init__ def __new__(cls, *args, **kwargs): print("__new__") # return object.__new__(cls) # 构造方法(监听python使用其类创建对象完成,给这个对象设置属性) def __init__(self): print("__init__") self.name = "小明" # 监听对象属性信息变化 def __str__(self): return "名字:%s" % self.name # 监听对象销毁 def __del__(self): print("再见") # 创建一个对象 xiaoming = Person() print(xiaoming) # None 空值类型 # <class 'NoneType'> print(type(None))
单例模式
# 单例模式 在程序中这个类创建出来的对象 只有一个(也就是占用一份内存地址) # 单例模式 也只会走一次__init__方法(保证这个单例对象的属性也是唯一的)(name=小明 age=20) # 合理的使用内存(避免内存浪费) class Person(object): # 定义一个类属性 保存这个类创建的对象 __instance = None # 定义一个类属性 判断是否是第一次走init方法 __is_first = True # 创建对象 # 重写new方法 是为了完成单例模式中的对象地址唯一 def __new__(cls, *args, **kwargs): # 判断是否通过这个类创建过对象 # 如果没有值需要创建 if not cls.__instance: # 创建对象保存起来 cls.__instance = object.__new__(cls) # 如果有值直接返回 return cls.__instance def __init__(self, name, age): # 判断是否是第一次 if Person.__is_first: # 赋值一次 self.name = name self.age = age # 设置类属性is_first 为False Person.__is_first = False # def make(self): # # hm = HMTest() # hm.my_func(20, 30) # 创建对象 xiaoming = Person("小明", 20) print(xiaoming.name) xiaohong = Person("小红", 21) print(xiaohong.name) xiaoyang = Person("小阳", 22) print(xiaoyang.name) # print(xiaoming.name, xiaohong.name, xiaoyang.name) # num = None # # 如果不为none 也就是真 # if not num: # print("测试") # 单例的好处? class HMTest(object): def my_func(self, a, b): return a + b # 在程序中 需要计算多次求和操作 比如1000次 可以省掉999分内存 # 每次使用 # 实例化一个对象 # hm = HMTest() # hm.my_func(10, 20) # 为了节约内存