今天是关于继承,权限,属性和方法,多态的知识,有点乱乱的,后期需要再复盘一下。
1.继承:描述类与类之间的所属关系。class 类 b(类a):pass,b可以使用a中的属性和方法。
b(子类,派生类),a(基类,父类)。
2.分类:单继承,多继承,多层继承。
3.重写:子类实现和父类名字相同的方法。
重写之后想要调用父类中的方法:1.父类名.方法名(self,其他参数)
2.super(类a.self).方法(参数)
3.super().方法名(参数)
4.权限:公有权限,私有权限(在属性和方法名钱前加两个下划线)
5.属性:实例属性,类属性
6.方法:实例方法(self),类方法(@classmethod)(cls),静态方法(@staticmethod)(参数无要求)
7.魔法属性:__dict__ :类型是字典,返回对象具有的属性
__mor__:查看继承顺序链
8.多态:在需要父类的时候也可以传入子类对象
# 继承:多个类之间的所属关系,基类(父类),派生类(子类)
# 基本语法 class 类B(类A):pass 称为类B继承了类A,B类的对象可以使用A类的属性和方法
# 优点:代码复用。
# 需求:1.定义一个动物类;2.在里面书写play方法;3.定义Dog类继承动物类;4.创建对象,调用
class Animal(object): # 对于动物类和object类来说,单继承
def paly(self):
print('palying')
class Dog(Animal): # 单继承,Dog--->Animal--->object 这种继承关系称为多层继承
def bark(self):
print('wangwang')
# 多层继承中,子类可以使用多有继承链中的方法和属性
class XTQ(Dog): # XTQ-->Dog单继承,XTQ-->Dog-->Animal类,多层继承
pass
xtq = XTQ()
xtq.bark() #调用父类方法
xtq.paly() #调用爷爷类方法
# dog = Dog()
# dog.paly()
# 继承分类:单继承和多层继承
# 单继承:如果一个类只有一个父类
# 多层继承:A-->B-->C
# 多继承:如果一个类有多个父类
# 重写:子类定义和父类重名的方法
# 重写原因:父类中的方法,不能满足子类对象的需求,所以要重写
# 特点:子类对象调用子类自己的方法,不再调用的方法,父类对象调用父类自己的方法
class Dog(object):
def bark(self):
print('wangwang')
class XTQ(Dog):
def bark(self):
print('aoaoao')
dog = Dog()
dog.bark()
xtq = XTQ()
xtq.bark()
# 重名之后子类调用父类的重名方法
class Dog(object):
def bark(self):
print('wangwang')
class XTQ(Dog):
def bark(self):
print('aoaoao')
def see_host(self):
print('see',end='')
# elf.bark() 不行 # 想要在子类调用子类同名方法
# 方法1:父类名.方法名(self,其他参数),通过此方法,不需要传递实参值,
# 解释器会自动将对象作为实参值传递给self形参,如果是类名.方法()调用,不会自动传递实参值,需要手动给self形参传递实参值
Dog.bark(self) # 注意传参
# 方法二:super(当前类,self).方法名(参数)
# 会调用当前类的父类方法
super(XTQ,self).bark()
# 方法三:是方法二的简写,super().方法名(参数)
super().bark()
pass
xtq = XTQ()
xtq.see_host()
# 继承中的init
class Dog(object):
def __init__(self,name):
self.age = 0
self.name = name
def __str__(self):
return f'name:{self.name},age:{self.age}'
class XTQ(Dog):
# 子类重写了父类的init方法,默认不再调用父类的init方法,需要手动调用父类init方法
def __init__(self,name,color): # 先写父类
super().__init__(name)
self.color = color
def __str__(self):
return f'name:{self.name},age:{self.age},color:{self.color}'
xtq = XTQ('小红','red')
print(xtq)
# 多继承(理解):如果一个类有两个及以上的父类
class Dog(object):
def bark(self):
print('wangwanmgwang')
def eat(self):
print('kenkenken')
class God(object):
def paly(self):
print('wanwan')
def eat(self):
print('pantao')
class XTQ(God,Dog): # 多继承
def eat(self):
print('重写eat,调用子类自己的方法')
# 调用指定父类中的方法
# Dog.eat(self)
# super(XTQ,self).eat() # 调用God,调用的是下一个类
# super(God,self).eat() # 调用的是Dog
pass
xtq = XTQ()
xtq.bark()
xtq.paly()
xtq.eat() # 若都存在相同方法,调用第一个父类中的方法
# 调用指定方法
# 类名.__mro__可以查看当前类的继承顺序连,也叫做调用顺序
# print(XTQ.__mro__)
# 权限:访问权限控制,使用范围
# 私有权限:在方法和属性前加上两个下划线,不能在类外部通过对象直接访问和使用,只能在内部
# 不能被子类继承,目的是保证数据的相对安全,想要访问和使用私有属性,定义一个公有的方法进行使用
# 公有:不是私有的就是公有的
class People(object):
def __init__(self):
# 钱不能随意被修改,定义成私有属性
# python中的私有本质是修改属性的名字,在创建对象的时候,会自动的修改属性名
# 在属性名的前面加上_类名前缀
self.__ICBC_money = 0
# 定义公有的方法,提供接口,修改余额
def get_money(self):
return self.__ICBC_money
def set_money(self,money):
self.__ICBC_money += money
xm = People()
# 实例对象:__dict__可以查看对象的属性信息,类型是字典
print('赋值之前',xm.__dict__)
xm.__ICB_money = 1000 # 添加了一个公有属性
print('赋值之后',xm.__dict__)
print('*'*30)
print(xm.get_money())
xm.set_money(1200)
print(xm.get_money())
xm.set_money(-200)
print(xm.__ICB_money)
# 私有方法:在方法的前边加上两个下划线,就为私有方法,不能在外部访问
# 作为类内部的方法使用,不让外部调用的时候去定义
class Dog(object):
def born(self):
print('生了一只')
self.__sleep()
def __sleep(self): # 私有
print('休息 30')
dog = Dog()
# dog.__sleep() 无法调用
dog.born()
# 类属性(理解)
# 对象(实例对象):通过class定义的类创建的,即通过类实例化来的
# 实例对象的属性称为实例属性,通过实例对象(self)定义的属性
# 实例属性:每个实例对象中都存在一份,并且值是可能是不一样的
# 类(类对象),是解释器在创建类的时候自动创建的
# 作用:通过类对象去定义实例对象,类对象可以保存一些属性信息,称为类属性
# 类属性的定义:在类内部,方法外部定义的变量就是类属性
# 类属性:内存中只有一份
# 怎么确认一个属性是该定义为实例属性还是类属性?
# 先假设为实例属性,查看这哥属性值对于不同的实例对象,属性值是否都一样,并且需要同时变化
# 如果是,就为类属性,不是就实例对象
class Dog(object):
# 类属性
class_name = '狗类'
def __init__(self,name,age):
# 实例属性
self.name = name
self.age = age
dog = Dog('huang',12)
print(dog.__dict__)
print(Dog.__dict__) # 类对象的属性
# 访问类属性,类名.类属性
print(Dog.class_name)
Dog.class_name = 'cat'
print(Dog.class_name)
# 修改类属性:类名.类属性=属性值
# 如果不存在和实例属性名相同的类属性,可以使用实例对象访问类属性的值
print(dog.class_name)
# 类方法:使用@classmethod装饰的方法,第一个参数是cls,代表的是类对象自己
# 如果在方法中使用了实例属性,那么该方法必须定义为实例方法
# 不需要使用实例属性,需要使用类属性,可以将这个方法定义为类方法
# 静态方法@staticmethod装饰的方法,对参数没有特殊要求
# 不需要使用实例属性,同时也不需要使用类属性
class Dog(object):
class_name = 'dog'
def __init__(self, name, age):
self.name = name
self.age = age
def paly(self): # 实例方法
print(f'P{self.name}play')
# def get_class(self): # 实例方法,因为没有使用实例属性,所以可以定义为类方法
# return Dog.class_name
# @classmethod #类方法标志
# def get_name(cls):
# return cls.class_name
@staticmethod
def show_info(): # 静态方法有参数就必须传递实参值
print('goggog')
dog = Dog('HUANG', 3)
dog.paly()
# print(dog.get_name())
# print(Dog.get_name())
dog.show_info()
Dog.show_info()
# 多态:在需要使用父类对象的地方,也可以传入子类对象,得到不同的结果
# 1.子类继承父类;2,子类重写父类中的同名方法;3.定义一个共同的方法,参数为父类,调用同名方法
class Dog(object):
def __init__(self,name):
self.name = name
def play(self):
print(f'{self.name}play')
class XTQ(Dog):
def play(self):
print(f'{self.name}paopao')
class Cat(object):
def __init__(self,name):
self.name = name
def play(self):
print(f'{self.name}lulu')
def play_with(obj_dog): # 传入不同对象
obj_dog.play()
dog = Dog('xiao') #父类
play_with(dog)
xtq = XTQ('hei')
play_with(xtq)
# 鸭子类型的多态:可以没有继承关系
cat = Cat('miao')
play_with(cat)
测试题:
list = [11,22,33,44,55,66,77,88,99,90]
my_dict = {'key1':[],'key2':[]}
for i in list:
if i > 66 :
my_dict['key1'].append(i)
else:
my_dict['key2'].append(i)
print(my_dict)
# 统计字符串的出现次数
my_str = 'hello world'
my_dict = {}
for i in my_str:
if i == ' ':
continue
my_dict[i] = my_str.count(i)
print(my_dict)
lass Person(object):
__count = 0
def __init__(self,name,age):
self.name = name
self.age = age
Person.__count += 1
@classmethod
def get_count(cls):
return cls.__count
@staticmethod
def show_info():
print('这是person类')
def study(self):
print(f'我的名字是{self.name},我要好好学习')
def __str__(self):
return f'我的名字是{self.name},我的年龄是{self.age}'
def __del__(self):
Person.__count -= 1
Person.show_info()
print(Person.get_count())
p = Person('小红',15)
print(p,p.get_count())
w = Person('xiao',1)
print(w,w.get_count())
p.study()
w.study()
del p
print(Person.get_count())
最近开始学习吴恩达的机器学习,冲冲冲!