1、定义类:
class Money:
pass
print(Money)
one = Money()
print(one)
print(one.__class__)
# class Money:
# pass
# print(Money.__name__) # __name__ == Money,Money既是类名,也是变量名
# xxx = Money
# print(xxx)
# print(xxx.__name__)
2、属性相关:
# class Person:
# pass
# p = Person()
# # 给p对象增加属性
# p.age = 18
# p.hight = 160
# # 访问属性
# print(p.age)
# print(p.__dict__)
# # 删除属性
# del p.hight
# print(p.hight)
# class Money:
# pass
# one = Money()
# Money.count = 1
# Money.age = 18
# print(Money.count)
# print(Money.__dict__)
# class Money:
# count = 1
# age = 18
# print(Money.count)
# print(Money.age)
# print(Money.__dict__)
# class Money:
# count = 1
# age = 18
# one = Money()
# print(one.__class__)
# print(one.count)
# print(one.age)
# class Test:
# sex = '男'
# class Money:
# count = 1
# age = 18
# one = Money()
# print(one.__class__)
# one.__class__ = Test
# print(one.__class__)
# print(one.count)
# print(one.age)
# print(one.sex)
# class Money:
# count = 1
# age = 18
# Money.age = 22
# print(Money.age)
# class Money:
# count = 1
# age = 18
# one = Money()
# print(Money.age)
# one.age = 19
# print(Money.age)
# class Money:
# count = 1
# age = 18
# one = Money()
# # del Money.age
# del one.age
# # print(Money.age)
# print(one.age)
# 实例对象的__dict__是可以改的
# class Money:
# pass
# one = Money()
# one.__dict__ = {'count': 1, 'age': 18}
# print(one.age)
# one.__dict__['age'] = 22
# print(one.age)
# print(one.__dict__)
# 类对象的__dict__是不能改的
# class Money:
# age = 18
# count = 1
# # Money.__dict__ = {'count': 1, 'age': 18} # 错误
# Money.__dict__['age'] = 22 # 错误
# print(Money.age)
# class Money:
# age = 18
# one = Money()
# two = Money()
# print(one.age)
# print(two.age)
# class Person:
# __slots__ = ['age', 'count'] # __slots__只能限制动态地添加实例属性和实例方法,而无法限制动态地添加类属性和类方法
#
# p1 = Person()
# p1.age = 18
# p1.num = 666 # 错误
# p2 = Person()
# p2.num = 999 # 错误
3、方法相关:
# class Person:
# def shilifangfa(self):
# print('这是一个实例方法', self)
#
# @classmethod
# def leifangfa(cls):
# print('这是一个类方法', cls)
#
# @staticmethod
# def jingtaifangfa():
# print('这是一个静态方法')
#
# p = Person()
# print(p)
# p.shilifangfa()
# Person.leifangfa()
# p.jingtaifangfa()
# Person.jingtaifangfa()
class Person:
def shilifangfa(self):
print('这是一个实例方法', self)
@classmethod
def leifangfa(cls):
print('这是一个类方法', cls)
@staticmethod
def jingtaifangfa():
print('这是一个静态方法')
p = Person()
print(p.__dict__)
# 所以方法都存储在类对象的__dict__里面
print(Person.__dict__)
4、实例方法:
class Person:
def eat(self, food):
print('在吃饭', food, self)
p = Person()
print(p)
p.eat('土豆') # 标准调用
Person.eat('nice', '土豆')
5、类方法:
class Person:
@classmethod
def leifangfa(cls, a):
print('这是一个类方法', cls, a)
Person.leifangfa(123) # 标准调用,通过类调用
p = Person()
p.leifangfa(123) # 通过实例调用
6、静态方法:
# class Person:
# @staticmethod
# def jingtai(a, b):
# print('这是一个静态方法', a, b)
#
# Person.jingtai(123, 456)
# p = Person()
# p.jingtai(123, 456)
class Person:
@staticmethod
def jingtai():
print('这是一个静态方法')
Person.jingtai()
p = Person()
p.jingtai()
7、不同类型的方法访问不同类型的属性_规律:
# class Person:
# age = 0
# p = Person()
# p.num = 10
#
# print(Person.age) # 类访问类属性
# print(p.age) # 实例访问类属性
# print(Person.num) # 错误,类访问实例属性
# print(p.num) # 实例访问实例属性
# class Person:
# age = 0
# def shilifangfa(self):
# print(self)
# print(self.age)
# print(self.num)
#
# p = Person()
# p.num = 10
# p.shilifangfa() # 实例访问实例方法
# Person.shilifangfa() # 错误,类访问实例方法
# Person.shilifangfa(p) # 若执意如此,必须手动传入第一个参数
# Person.shilifangfa('suibian')
# class Person:
# age = 0
# @classmethod
# def leifangfa(cls):
# print(cls)
# print(cls.age)
# # print(cls.num) # 错误
#
# p = Person()
# p.num = 10
# p.leifangfa() # 实例访问类方法
# Person.leifangfa() # 类访问类方法
class Person:
age = 18
@staticmethod
def jingtaifangfa():
print(Person.age)
print(p.age)
p = Person()
p.num = 10
Person.jingtaifangfa()
p.jingtaifangfa()
8、元类:
# num = 10
# print(num.__class__)
#
# s = 'abc'
# print(s.__class__)
#
# class Person:
# pass
# p = Person()
# print(p.__class__)
#
# # 元类type:创建类对象的类
# print(int.__class__)
# print(str.__class__)
# print(Person.__class__)
# print(type.__class__)
# #使用元类创建类对象
# def run(self):
# print('测试', self)
#
# xxx = type('Person', ('父类1', '父类2', ……), {'count': 0, 'age': 18, 'run': run})
# print(xxx)
# print(xxx.__dict__)
# # print(Person.__dict__) # 错误,Person是类名是一个属性,xxx是变量才指向Person类
# p = xxx()
# p = Person()
# print(p)
# p.run()
# __metaclass__ = xxx
#
# class Human:
# __metaclass__ == xxx
# pass
#
# class Person(Human):
# __metaclass__ == xxx # 自身指明元类方式一,元类检索机制:自己-->父类-->类外-->type
# pass
#
# class Person(Human, __metaclass__=xxx): # 自身指明元类方式二
# pass
9、类的描述:
class Person:
"""
关于这个类的描述,类的作用,类的构造函数……;
关于类属性的描述
"""
count = 0
def run(self, distance, step):
"""
这个方法的作用效果:
:param distance:该参数的含义,参数的类型,是否有默认值
:param step:该参数的含义,参数的类型,是否有默认值
:return:返回结果的含义,返回数据的类型
"""
print('xxx')
return distance/step
print(help(Person))
10-a、私有属性:
"""
不同作用域对共有属性、半私有属性、私有属性的操作权限
"""
# class Animal:
# x = 10
# def test(self):
# print(Animal.x)
# print(self.x)
#
# class Dog(Animal):
# def test2(self):
# print(Dog.x)
# print(self.x)
#
# # 测试代码
# a = Animal()
# a.test()
# d = Dog()
# d.test2()
# print(Animal.x)
# print(Dog.x)
# print(a.x)
# print(d.x)
# a = 666
# class Animal:
# _x = 10
# def test(self):
# print(Animal._x)
# print(self._x)
#
# class Dog(Animal):
# def test2(self):
# print(Dog._x)
# print(self._x)
#
# # 测试代码
# a = Animal()
# a.test()
# d = Dog()
# d.test2()
# print(Animal._x)
# print(Dog._x)
# print(a._x)
# print(d._x)
# # __all__ = ['_a']
# _a = 666
# class Animal:
# __x = 10
# def test(self):
# print(Animal.__x)
# print(self.__x)
#
# class Dog(Animal):
# def test2(self):
# print(Dog.__x)
# print(self.__x)
#
# 测试代码
# a = Animal()
# a.test()
# d = Dog()
# d.test2()
# print(Animal.__x)
# print(Dog.__x)
# print(a.__x)
# print(d.__x)
# __all__ = ['__a']
# __a = 666
# class Animal:
# # __x = 10
# def test(self):
# print(Animal.__x) # 错误,在类的外部定义了属性__x,然后在类的内部直接访问__x会报错AttributeError: type object 'Animal' has no attribute '_Animal__x',
# print(self.__x) # 错误,在类的外部定义了属性__x,然后在类的内部直接访问__x会报错AttributeError: type object 'Animal' has no attribute '_Animal__x',
# pass
#
# a = Animal()
# Animal.__x = 10 # 在类的外部定义类属性__x,只是普通属性而非私有属性
# a.test()
# print(Animal.__dict__)
# # print(Animal._Animal__x) # 错误
# class Animal:
# def test(self):
# # self.__y = 18
# print(self.__y) # 错误,在类的外部定义了属性__y,然后在类的内部直接访问__y会报错AttributeError: 'Animal' object has no attribute '_Animal__y'
# pass
#
# a = Animal()
# a.__y = 18 # 在类的外部定义实例属性__x,只是普通属性而非私有属性
# a.test()
# print(a.__dict__)
# # print(a._Animal__y) # 错误
"""
私有属性的应用场景
"""
class Person:
def __init__(self):
self.__age = 18
def setage(self, value):
if isinstance(value, int) and 0 < value < 150:
self.__age = value
else:
print("您输入的数据有误,请重新输入")
def getage(self):
return self.__age
def delage(self):
del self.__age
p = Person()
# print(p._Person__age) # 不要在类的外部这样子访问私有属性,违背了‘私有’的‘初衷’
# 访问、修改、删除私有属性应当在类的内部
p.setage(100)
print(p.getage())
# class_与关键字class做区分
# __init__是系统内置的东西
10-b、私有属性模块外访问:
# import 10私有化属性
# print(10私有化属性.a)
# from 10私有化属性 import *
# print(_a)
# import 10私有化属性
# print(10私有化属性.a)
# from 10私有化属性 import * # 需要先在10私有化属性.py模块中需设置__all__ = ['_a'],否则报错
# print(_a)
# import 10私有化属性
# print(10私有化属性.__a)
# from 10私有化属性 import * # 需要先在10私有化属性.py模块中需设置__all__ = ['__a'],否则报错
# print(__a)
11、只读属性的设计:
# # 方案一
# class Person(object):
# def __init__(self):
# self.__age = 18
#
# @property # 以使用属性的方式使用方法
# def getage(self):
# return self.__age
#
# p = Person()
# # print(p.getage())
# print(p.getage)
# p.getage = 22 # 错误
# print(Person.__bases__) # 查看该类的父类
# class Person(object):
# @property # 以使用属性的方式使用方法
# def age(self):
# print('-----------getage')
# return self.__age
#
# @age.setter
# def age(self, value):
# print('-----------setage')
# self.__age = value
#
# @age.deleter
# def age(self):
# print('-----------delage')
# del self.__age
#
# p = Person()
# p.age = 18 # 此时既定义了一个私有实例属性,又定义了一个类属性age
# print(p.age)
# print(p.__dict__)
# print(Person.__dict__)
# p.age = 22
# Person.age = 22 # 此时是修改类属性age
# print(p.__dict__)
# print(Person.__dict__)
# class Person(object):
# def getage(self):
# print('-----------getage')
# return self.__age
#
# def setage(self, value):
# print('-----------setage')
# self.__age = value
#
# def delage(self):
# print('-----------delage')
# del self.__age
#
# age = property(getage, setage, delage, '就这个feel') # 你懂得!这是一个类属性
#
# p = Person()
# p.age = 18
# print(p.age)
# print(p.__dict__)
# print(Person.__dict__)
# Person.age = 22 # 此时是修改类属性age
# print(p.__dict__)
# print(Person.__dict__)
# # 方案二
# class Person:
# # 当通过"实例.属性=值"给一个实例增加一个属性,或修改属性值的时候,都会调用这个方法,
# # 只有在这个方法内部才会真正把这个属性及对应的值存储到__dict__字典里
# def __setattr__(self, key, value):
# print(key, type(key), value, type(value))
# if key == 'age':
# print('这个属性是只读属性,不能设置')
# else:
# self.__dict__[key] = value
#
# p = Person()
# p.age = 18
# p.height = 120
# print(p.__dict__)
# print(p.age) # 错误,只读属性无法添加进__dict__
class Person:
# 当通过"实例.属性=值"给一个实例增加一个属性,或修改属性值的时候,都会调用这个方法,
# 只有在这个方法内部才会真正把这个属性及对应的值存储到__dict__字典里
def __setattr__(self, key, value):
print(key, type(key), value, type(value))
if key == 'age' and key in self.__dict__.keys():
print('这个属性是只读属性,不能设置')
else:
self.__dict__[key] = value
p = Person()
p.age = 18
p.height = 120
print(p.__dict__)
print(p.age)
12、私有方法:
class Person:
__age = 18
def __run(self):
print('ccc')
def _Person__run(self): # 该方法将上面的方法覆盖了
print('xxxxxx')
p = Person()
p._Person__run()
print(Person.__dict__)
13、方法补充:
"""
-----------------------------__str__方法面向普通用户,__repr__方法面向开发人员、解释器----------------------------
"""
# class Person:
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def __str__(self):
# print('xxx') # 注意__str__()方法必须要有return返回值,只有print会报错
# return f'{self.name}今年 {self.age}岁 !!!'
#
# p = Person('Bob', 12)
# print(p)
# print(str(p), type(str(p))) # 与上述所走流程不同
#
# class Person:
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def __repr__(self):
# print('yyy') # 注意__repr__()方法必须要有return返回值,只有print会报错
# return f'{self.name}今年 {self.age}岁 !!!'
#
# p = Person('Bob', 12)
# print(p)
# print(repr(p), type(repr(p))) # 与上述所走流程不同
# class Person:
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def __str__(self):
# print('xxx') # 注意__str__()方法必须要有return返回值,只有print会报错
# return f'{self.name}今年 {self.age}岁 !!!'
#
# p = Person('8848钛金手机', 18)
# print(p)
# print(str(p))
# print(repr(p)) # 返回对象的本质<__main__.Person object at 0x000001ECAF2E1408>
#
# class Person:
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def __repr__(self):
# print('yyy') # 注意__repr__()方法必须要有return返回值,只有print会报错
# return f'{self.name}今年 {self.age}岁 !!!'
#
# p = Person('8848钛金手机', 18)
# print(p)
# print(repr(p))
# print(str(p)) # 返回同上
# class Person:
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def __str__(self):
# print('xxx') # 注意__str__()方法必须要有return返回值,只有print会报错
# return f'{self.name}今年 {self.age}岁 !!!'
#
# def __repr__(self):
# print('yyy') # 注意__repr__()方法必须要有return返回值,只有print会报错
# return f'{self.name}今年 {self.age}岁 !!!'
#
# p = Person('8848钛金手机', 18)
# print(p)
# print(str(p))
# print(repr(p))
"""
---------------------------------------- __call__方法,及其应用场景------------------------------------------
使实例对象像函数一样,能够被调用
"""
# class Person:
# # def __call__(self, *args, **kwargs): # 可以使实例对象像函数一样可以被调用
# # print('xxx', args, kwargs)
# pass
#
# p = Person()
# p(12, 13, key=14)
# print(dir(p))
# print('创建了一个%s类型的画笔,它是%s颜色' % ('钢笔', '红色'))
# print('创建了一个%s类型的画笔,它是%s颜色' % ('钢笔', '蓝色'))
# print('创建了一个%s类型的画笔,它是%s颜色' % ('钢笔', '黑色'))
# print('创建了一个%s类型的画笔,它是%s颜色' % ('铅笔', '黑色'))
#
# def createPen(p_type, p_color):
# print('创建了一个%s类型的画笔,它是%s颜色' % (p_type, p_color))
# createPen('钢笔', '红色')
# createPen('钢笔', '蓝色')
# createPen('钢笔', '黑色')
#
# def createPen(p_color, p_type):
# print('创建了一个%s类型的画笔,它是%s颜色' % (p_type, p_color))
# import functools
# gangbiFunc = functools.partial(createPen, p_type='钢笔')
# gangbiFunc('红色')
# gangbiFunc('蓝色')
# gangbiFunc('黑色')
#
# class PenFactory:
# def __init__(self, p_type):
# self.p_type = p_type
#
# def __call__(self, p_color):
# print('创建了一个%s类型的画笔,它是%s颜色' % (self.p_type, p_color))
#
# gangbiF = PenFactory('钢笔')
# gangbiF('红色')
# gangbiF('蓝色')
# gangbiF('黑色')
"""
---------------------------__setitem__、__getitem__、__delitem__:索引操作---------------------------
可以使实例对象像字典、列表一样进行索引操作
"""
# class Person:
# def __init__(self):
# self.cache = {}
#
# def __setitem__(self, key, value):
# print("setitem", key, value)
# self.cache[key] = value
#
# def __getitem__(self, item):
# print("getitem", item)
# return self.cache[item]
#
# def __delitem__(self, key):
# print("delitem", key)
# del self.cache[key]
#
# p = Person()
# p['name'] = 'gg'
# print(p['name'])
# del p['name']
# print(p.cache)
"""
----------------------------------__setitem__、__getitem__、__delitem__:切片操作------------------------------
可以使实例对象像列表、元组、字符串一样进行切片操作
"""
# class Person:
# def __setitem__(self, key, value):
# print("setitem", key, value)
# print(key.start, key.stop, key.step)
#
# def __getitem__(self, item):
# print("getitem", item)
#
# def __delitem__(self, key):
# print("delitem", key)
#
# p = Person()
# p[0:4:2] = [1, 2]
# p[0::2]
# del p[1:4]
# class Person:
# def __init__(self):
# self.item = [1, 2, 3, 4, 5, 6, 7, 8]
#
# def __setitem__(self, key, value):
# print("setitem", key, value)
# self.item[key] = value
# # if isinstance(key, slice):
# # self.item[key.start:key.stop:key.step] = value
#
# def __getitem__(self, item):
# print("getitem", item)
#
# def __delitem__(self, key):
# print("delitem", key)
#
# p = Person()
# p[0:4:2] = ['a', 'v']
# print(p.item)
"""
--------------------------------------六种方法:比较操作-------------------------------------
可以直接使用实例对象进行比较操作
"""
# class Person:
# def __init__(self, age, hight):
# self.age = age
# self.hight = hight
#
# def __eq__(self, other): # other是比较符右侧的对象
# print('eq')
# return self.age == other.age
#
# def __ne__(self, other):
# print('ne')
#
# def __gt__(self, other):
# print('gt')
#
# def __ge__(self, other):
# print('ge')
#
# def __lt__(self, other):
# print('lt')
#
# def __le__(self, other):
# print('le')
#
# p1 = Person(18, 160)
# p2 = Person(17, 190)
# print(p1 == p2)
# class Person:
# def __init__(self, age, hight):
# self.age = age
# self.hight = hight
#
# def __lt__(self, other):
# print('lt')
# print(self.age, other.age)
# return self.age < other.age
#
# p1 = Person(18, 160)
# p2 = Person(19, 190)
# print(p1 < p2)
# print(p1 > p2) # 相当于p2 < p1,此时对应的self、other与上行代码的相反
## >= 不能通过__gt__、__eq__方法的叠加来实现,而应用__ge__方法
# # 通过模块实现比较方法的叠加
# import functools
# @functools.total_ordering
# class Person:
# def __init__(self, age, hight):
# self.age = age
# self.hight = hight
#
# def __lt__(self, other):
# print('lt')
# return self.age < other.age
#
# def __eq__(self, other):
# print('eq')
# return self.age == other.age
#
# p1 = Person(180, 160)
# p2 = Person(19, 190)
# print(p1 <= p2)
"""
----------------------------------------__bool__方法--------------------------------------
通过该方法确定实例对象在上下文环境中的布尔值
"""
# class Person:
# def __init__(self):
# self.age = 10
#
# def __bool__(self):
# return self.age >= 1
#
# p = Person()
# if p:
# print('xxx')
"""
---------------------------------__getitem__、__iter__方法:遍历操作-----------------------------
__iter__方法的优先级高于__getitem__方法
"""
## 方式一:
# class Person:
# def __init__(self):
# self.result = 1
#
# def __getitem__(self, item):
# self.result += 1
# if self.result >= 6:
# raise StopIteration('停止遍历')
# return self.result
#
# p = Person()
# for i in p:
# print(i)
## 方式二(迭代器详述):https://blog.csdn.net/world_in_world/article/details/127755621
## 方式三:
# class Person:
# def __init__(self):
# self.age = 1
#
# def __iter__(self):
# print('xxx') # 没有走进该方法
# self.age = 1
# return self
#
# def __next__(self):
# print('yyy')
# self.age += 1
# if self.age >= 6:
# raise StopIteration('Stop')
# return self.age
#
# p = Person()
# # pt = iter(p, 4) # 错误,TypeError: iter(v, w): v must be callable
# pt = iter(p.__next__, 4)
# for i in pt:
# print(i)
## 方式四:
# class Person:
# def __init__(self):
# self.age = 1
#
# def __iter__(self):
# print('xxx') # 没有走进该方法
# self.age = 1
# return self
#
# def __call__(self):
# print('yyy')
# self.age += 1
# if self.age >= 6:
# raise StopIteration('Stop')
# return self.age
#
# p = Person()
# pt = iter(p, 4)
# for i in pt:
# print(i)
# # 实例
# class MyList(object):
# """自定义的一个可迭代对象"""
# def __init__(self):
# self.items = []
#
# def add(self, val):
# self.items.append(val)
#
# def __iter__(self):
# myiterator = MyIterator(self)
# return myiterator
#
# class MyIterator(object):
# """自定义的供上面可迭代对象使用的一个迭代器"""
# def __init__(self, mylist):
# self.mylist = mylist
# # current用来记录当前访问到的位置
# self.current = 0
#
# def __next__(self):
# if self.current < len(self.mylist.items):
# item = self.mylist.items[self.current]
# self.current += 1
# return item
# else:
# raise StopIteration
#
# def __iter__(self):
# return self
#
# if __name__ == '__main__':
# mylist = MyList()
# mylist.add(1)
# mylist.add(2)
# mylist.add(3)
# mylist.add(4)
# mylist.add(5)
# for num in mylist:
# print(num)
"""
---------------------------------__get__、__set__、__delete__方法:描述器------------------------------
只要实现了三个方法中任意一个方法的类实例化出的对象就可称为描述器;一般通过实例对象操作描述器对象,而不通过类;描述器只在新式类中生效,在经典类中无法生效
"""
## 定义方式一:
# class Person(object):
# def getage(self):
# print('-----------getage')
# return self.__age
#
# def setage(self, value):
# print('-----------setage')
# self.__age = value
#
# def delage(self):
# print('-----------delage')
# del self.__age
#
# age = property(getage, setage, delage, '这是个描述器') # age是一个描述器,当然也是一个类属性
#
# p = Person()
# help(Person) # 可以看到 Data descriptors defined here:
# p.age = 18
# print(p.age)
# del p.age
# print(Person.age) # 类操作描述器,描述器无法生效
# Person.age = 18
# del Person.age
## 定义方式二:
# class Age:
# def __get__(self, instance, owner):
# print('get')
#
# def __set__(self, instance, value):
# print('set')
#
# def __delete__(self, instance):
# print('delete')
#
# class Person:
# age = Age()
#
# p = Person()
# p.age = 18
# print(p.age)
# del p.age
# print(Person.age) # 类操作描述器,描述器局部生效
# Person.age = 18
# del Person.age
## 描述器与实例属性重名时,操作优先级
## 资料描述器:至少实现了__get__、__set__方法
## 非资料描述器:仅仅实现了__get__方法
## 资料描述器 > 实例属性 > 非资料描述器
# class Age:
# def __get__(self, instance, owner):
# print('get')
#
# def __set__(self, instance, value):
# print('set')
#
# def __delete__(self, instance):
# print('delete')
#
# class Person:
# age = Age()
# def __init__(self):
# self.age = 18
#
# p = Person()
# p.age = 18
# print(p.__dict__)
## 不同Age实例共享同一age,数据存储应用Person实例
# class Age:
# def __get__(self, instance, owner):
# print('get', self, instance, owner)
# return self.v
# # return instance.v
#
# def __set__(self, instance, value):
# print('set', self, instance, value)
# self.v = value
# # instance.v = value
#
# def __delete__(self, instance):
# print('delete', instance)
#
# class Person:
# age = Age()
#
# p1 = Person()
# p1.age = 18
# print(p1.age)
# p2 = Person()
# p2.age = 10
# print(p2.age)
# print(p1.age)
14、对象的生命周期:待补充……
待补充,敬请期待……
15、内存管理机制:待补充……
待补充,敬请期待……
16、继承:待补充……
"""
继承:一个类”拥有“另一个类的”资源“的方式之一。
”拥有“:不是对”资源“的复制,也不是对”资源“的剪切移动,而是“资源”的使用权;
“资源”:指的是非私有的属性和方法。
"""
"""
区分__class__和__bases__属性,即区分type和object
"""
# class Animal:
# pass
#
# class xxx(object):
# pass
#
# class Dog(Animal, xxx):
# pass
#
# d = Dog()
# print(Dog.__bases__)
# print(Dog.__class__)
# print(xxx.__bases__)
# print(xxx.__class__)
# print(Animal.__bases__)
# print(Animal.__class__)
# --------------------------------------------资源的使用---------------------------------------------
"""
测试某个资源能否被继承
"""
# class Animal:
# a = 1
# _b = 2
# __c = 3 # 错误
#
# def t1(self):
# print('t1')
#
# def _t2(self):
# print('t2')
#
# def __t3(self): # 错误
# print('t3')
#
# def __init__(self):
# print('init, Animal')
#
# class Person(Animal):
# def test(self):
# print(self)
# print(self.a)
# print(self._b)
# print(self.__c)
#
# self.t1()
# self._t2()
# self.__t3()
# self.__init__()
#
# p = Person()
# p.test()
"""
继承来的资源仅仅是能读取,而不能设置
"""
# class B:
# age = 10
#
# class A(B):
# pass
#
# print(A.age)
# A.age = 18 # 只是给类A新增类属性age,而不是修改类B的类属性age
# # del A.age # 报错
# print(A.age)
# print(B.age)
# print(A.__dict__)
# print(B.__dict__)
"""
单继承、无重叠的多继承、有重叠的多继承:继承算法的演变,之后补充
"""
# ------------------------------------------资源的覆盖(重写)------------------------------------------
"""
优先级了造成覆盖的假象,当调用优先级比较高的资源时,注意self、cls的变化
"""
# --------------------------------------------资源的累加--------------------------------------------
"""
继承中的__init__方法
"""
# class B:
# a = 1
# def __init__(self):
# print('xxx')
# self.b = 2
#
# class A(B):
# pass
#
# a_obj = A()
# print(A.a)
# print(a_obj.b)
"""
方案一:__init__方法
"""
# class B:
# a = 1
# def __init__(self):
# print('xxx')
# self.b = 2
# self.c = 999
#
# class A(B):
# def __init__(self):
# print('yyy')
# B.__init__(self)
# self.d = 666
#
# a_obj = A()
# print(a_obj.__dict__)
"""
方案二:在低优先级类的方法中,通过super调用高优先级类的方法
概念:super是一个类,只在新式类中有效
作用:起着代理的作用,帮我们完成以下任务——>沿着MRO链条,找到下一级节点,去调用对应的方法
test:1、沿着谁的MRO链条?
2、找谁的下一节点?
3、如何应对类方法、静态方法以及实例方法的传参问题?
语法原理:一、语法格式:super(参数1[, 参数2])
二、工作原理:def super(cls, inst):
mro = inst.__class__.mro()
return mro[mro.index(cls) + 1]
三、问题解决:1、沿着谁的MRO链条?——>参数2:本类,本类的实例,本类的子类,本类子类的实例
2、找谁的下一节点?——>参数1:本类
3、如何应对类方法、静态方法以及实例方法的传参问题?——>使用参数2进行调用
四、具体语法形式:1、super(type, obj)——>Python2.2+、Python3+
2、super(type, type2)——>Python2.2+、Python3+
3、super()——>Python3+
注意事项:1、super和父类(超类)没有实质性的关联
2、保证调用形式的统一:要是类名调用, 全是类名调用;要是super调用, 全是super调用
"""
# class B:
# a = 1
# def __init__(self):
# self.b = 2
# self.xxx = '123'
#
# def t1(self):
# print('t1')
#
# @classmethod
# def t2(cls):
# print('t2')
#
# @staticmethod
# def t3():
# print('t3')
#
# class A(B):
# c = 3
# def __init__(self):
# # super(A, self).__init__()
# super().__init__() # 同上
# self.e = 666
#
# def tt1(self):
# print('tt1')
#
# @classmethod
# def tt2(cls):
# # super(A, A).t2()
# super().t2()
# print('tt2')
#
# @staticmethod
# def tt3():
# print('tt3')
#
# a = A()
# # print(a.__dict__)
# A.tt2()
# # test:重复调用了D类里面的__init__方法
# class D:
# def __init__(self):
# print('d')
#
# class C(D):
# def __init__(self):
# D.__init__(self)
# print('c')
# class B(D):
# def __init__(self):
# D.__init__(self)
# print('b')
# class A(B, C):
# def __init__(self):
# B.__init__(self)
# C.__init__(self)
# print('a')
# a = A()
# # 上述问题解决
# class D:
# def __init__(self):
# print('d')
#
# class C(D):
# def __init__(self):
# super().__init__()
# print('c')
# class B(D):
# def __init__(self):
# super().__init__()
# print('b')
# class A(B, C):
# def __init__(self):
# super().__init__()
# print('a')
# a = A()
# # 注意事项一:super和父类(超类)没有实质性的关联
# class D:
# def __init__(self):
# print('d')
# class B(D):
# def __init__(self):
# super(self.__class__, self).__init__() # 这种写法不稳定,不推荐
# print('b')
# class A(B):
# def __init__(self):
# super().__init__()
# print('a')
#
# B() # 可行
# # A() # 不可行
# # 注意事项二:保证调用形式的统一,混合使用容易出现重复调用问题
# class D:
# def __init__(self):
# print('d')
#
# class C(D):
# def __init__(self):
# super().__init__()
# print('c')
# class B(D):
# def __init__(self):
# super().__init__()
# print('b')
# class A(B, C):
# def __init__(self):
# B.__init__(self)
# C.__init__(self)
# print('a')
# a = A()
# print(A.mro())
17、多态:待补充……
待补充,敬请期待……