重要思想:python中万物皆对象!
1、函数重写(有了的前提下改写)
- 重写:override(v. (以权力)否决,推翻)在继承的前提下,如果在子类中重新实现了父类中的函数,才能进行函数重写。
- 自定义函数的重写:
- 1.什么时候需要重写函数
如果一个类有很多的子类,一部分子类可以直接继承父类中的函数实现的功能。
但是,如果父类中实现的需求满足不了个别子类的使用,则需要在子类中重写父类中的函数。
- 2.重写需要注意的事项
保留函数的声明部分【def xxxx(形参列表)】
重新实现函数的实现部分【函数体】
class P(object):
def __init__(self,id_P):
self.id_P = id_P
def f1(self):
print('父类P~~~~~~')
class B(object):
def __init__(self,id_B):
self.id_B = id_B
def f1(self):
print('父类B~~~~~~')
class PB(P,B):
pass
pb = PB(1)
pb.f1()
class P1(P):
def f1(self):
print('子类P1~~~~~~')
p1 = P1(1)
p1.f1()
class P2(P):
def f1(self):
P.f1(self)
print('子类P2~~~~~~')
p2 = P2(2)
p2.f1()
class Animal():
def walk_style(self):
print("走路")
class Cat(Animal):
pass
class Dog(Animal):
pass
class Bird(Animal):
def walk_style(self):
Animal.walk_style(self)
print("飞行")
class Fish(Animal):
def walk_style(self):
print("游走")
cat = Cat()
cat.walk_style()
bird = Bird()
bird.walk_style()
fish = Fish()
fish.walk_style()
"""
__str__:返回对象的字符串描述信息,面向用户
__repr__:返回对象的字符串描述信息,面向程序员
"""
class Person1(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Person1('小张',18)
print(p1)
class Person2(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return f"姓名:{self.name},年龄:{self.age}"
p2 = Person2('小张',18)
print(p2)
print(p2.__str__())
p21 = Person2('小李',18)
p22 = Person2('小吴',20)
l = [p2,p21,p22]
print(l)
for i in l:
print(i)
class Person3(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return f"姓名:{self.name},年龄:{self.age}"
__repr__ = __str__
p3 = Person3('小张',18)
l1= [p3]
print(l1)
n = 1
print(n)
2、运算符重载(不支持变为支持)
函数重写(override) | 必须是在继承的前提下 |
---|
运算符重载(overload) | 对于自定义的类,通过该类创建的对象,不支持某些运算符的使用,则可以重载对应的函数 |
- 通过dir函数可以查看对应的数据类型支持那些方法(包括运算符)
- 如: +:add *:mul 等算术运算符
- 如:>:gt <:lt ==:eq !=:ne >=:ge <=:__le__等关系运算符
print(34 + 45)
print('hello' + 'Python')
print("hello".__add__("Python"))
print([1,2,3] + [3,5,6])
print([1,2,3].__add__([3,5,6]))
class Person():
def __init__(self,height):
self.height = height
def __str__(self):
return str(self.height)
__repr__ = __str__
p1 = Person(180)
p2 = Person(163)
'''#重载__add__
注意:结合实际情况,一般两个对象相加是没法相加的,都是对象的属性相加
需求:两个Person的对象相加,实际操作的是身高
问题1:Person + Person ----->int
正确:Person + Person ----->Person
解决方案:return self.height + other.height ------> return Person(self.height + other.height)
问题2:打印p1 + p2结果是一个对象的地址
解决方案:重写__str__,返回str(self.height)
'''
class Person1():
def __init__(self,height):
self.height = height
def __str__(self):
return str(self.height)
__repr__ = __str__
def __add__(self, other):
return Person(self.height + other.height)
p11 = Person1(180)
p12 = Person1(163)
print(p11 + p12)
print(p11.__add__(p12))
"""
>:__gt__ greater than
<:__lt__ less than
==:__eq__ equal
!=:__ne__ not equal
>=:__ge__ greater equal
<=:__le__ less equal
"""
class Person2():
def __init__(self,height):
self.height = height
def __gt__(self, other):
return self.height > other.height
p21 = Person2(180)
p22 = Person2(163)
print(p21 > p22)
print(p21.__gt__(p22))
3、类方法和静态方法
- 注意:现在学完了类之后,以后写类需要有的一些必备元素:
class Full(object):
__slots__ = ('name','age')
n = 0
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def f1(cls):
print('这是类函数~~~')
def f2(self):
print('这是实例函数~~~')
@staticmethod
def f3():
print('这是静态函数~~~')
def __str__(self):
return self.name
__repr__ = __str__
p_t = Full('张',15)
p_t.f1()
p_t.f2()
p_t.f3()
Full.f1()
Full.f3()
'''
总结:
【面试题】简述实例函数,类函数和静态函数之间的区别和联系
不同点:
a.是否有装饰器装饰:实例函数无需装饰器装饰,类函数需要使用@classmethod装饰,静态函数需要使用@staticmethod装饰
b.形参不同:实例函数的第一个参数为self,类函数的第一个参数为cls,静态函数的参数没有要求
c.调用不同:类函数和静态函数都可以通过对象 或者 类 调用,但是,实例函数只能通过对象调用 (对象可以调所有,类不能调实例函数)
d.使用场景不同:如果要封装一个工具类,对参数没有要求,则尽量使用静态函数,如果有要求,则使用类函数
在实际项目开发中,使用实例函数较多。
相同点(他们本身都是函数):
a.可以使用默认参数,关键字参数,不定长参数
b.可以使用返回值
'''
class Math(object):
@staticmethod
def add(num1,num2):
return num1 + num2
@staticmethod
def sub(num1, num2):
return num1 - num2
@staticmethod
def mul(num1, num2):
return num1 * num2
@staticmethod
def div(num1, num2):
return num1 / num2
print(Math.add(34,5))
print(Math.sub(34,5))
print(Math.mul(34,5))
print(Math.div(34,5))
4、对象的其他概念
- 对象的内置属性:可以理解为对象的系统属性
- 注意:内置属性__slots__作为限制,有时候会导致对象无法调用内置属性
- 对象的内置函数:可以理解为对象的系统函数
class Person():
__slots__ = ("name",)
class Check(object):
"""
功能:实现数据的校验
"""
def show(self):
pass
print(Check.__doc__)
'''
打印结果:
功能:实现数据的校验
'''
class Pe(object):
place = "地球"
def __init__(self, name):
self.name = name
def show(self):
pass
@classmethod
def func1(cls):
pass
@staticmethod
def func2():
pass
def __str__(self):
return self.name
__repr__ = __str__
print(Pe.__dict__)
a = Pe('f')
print(a.__dict__)
'''
总结:
a.对象.__dict__只能获取对象(实例)属性
b.类名.__dict__可以获取类中的类属性,结构函数,实例函数,类函数和静态函数
c.__dict__获取的数据是通过字典的形式展现
'''
p = Pe('aaa')
print(p.__module__)
print(__name__)
'''
功能:
a.在函数中“if __name__ == '__main__':”相当于主函数入口。
b.用来做工具模块的测试,只有在工具模块中运行,在其他文件中调用不执行。
c.__name__属性特殊之处在于可以直接调用
'''
a = 45
b = 46
print(id(a) == id(b))
print(a is b)
print(type("fajgh"))
print(type("abc") == str)
print(type("123") == type(123))
print(type(type(123)))
l11 = [1, 2, 3, 4, 'dd', '33', 55]
l12 = [i for i in l11 if type(i) == str]
print(l12)
class Per_son(object):
pass
p = Per_son()
print(type(p))
import types
print(type(lambda x:x ** 2) == types.LambdaType)
print(type((i for i in range(5))) == types.GeneratorType)
print(type("abc") == str)
print(isinstance("abc",str))
print(dir(34))
class Animal(object):
def __init__(self,name):
self.name = name
def eat(self):
print("eating")
class Cat(Animal):
pass
class LittleCat(Cat):
pass
print(issubclass(Cat,Animal))
print(issubclass(Cat,object))
print(issubclass(LittleCat,Animal))
print(issubclass(Animal,Cat))