一、关于None和判断的总结
1.1、None是什么?
- 与C和JAVA不同,python中是没有
NULL
的,取而代之的是None
。 None
是一个特殊的常量,表示变量没有指向任何对象。- 在Python中,
None
本身实际上也是对象,有自己的类型NoneType
。 - 你可以将
None
赋值给任何变量,但我们不能创建NoneType
类型的对象
obj = None
obj2 = None
print(type(None))
print(id(None))
print(id(obj))
print(id(obj2))
执行结果:
<class 'NoneType'>
140717958924280
140717958924280
140717958924280
⚠️None不是False,None不是0,None不是空字符串。None和任何其他的数据类型比较永远返回False。
1.2、None和其他类型的比较
-
None和其他任何类型比较都会返回False
a = None if a is None and a==None: print("a是None") #会执行 if a==False or a==0: print("None不等于False") #不会被打印
-
空列表、空字符串、0之间的比较
1、if语句判断时,空列表[]、空字典{}、空元组()、0等一系列代表空和无的对象会被转换成False
a=[];b=();c={};d="";e=0;f=None
if (not a) and (not b) and (not c) and (not d) and (not e) and (not f):
print("if判断时,空列表[]、空字符串、0、None等代表空和无的对象会被转换成False")
2、==
和is
判断时,空列表、空字符串不会自动转成False
a=[];b=();c={};d="";e=0;
if (a==False or d==False):
print("==时,空列表、空字符串不是False!") #不会执行
if(e==False):
print("==时,0会转成False")
二、面向对象三大特征介绍
Python是面向对象的语言,支持面向对象编程的三大特性:继承、封装(隐藏)、多态。
2.1、封装(隐藏)
隐藏对象的属性和实现细节,只对外提供必要的方法。相当于将“细节封装起来”,只对外暴露“相关调用方法”。
通过前面学习的“私有属性、私有方法”的方式,实现“封装”。Python追求简洁的语法,没有严格的语法级别的“访问控制符”,更多的是依靠程序员自觉实现。
2.2、继承
继承可以让子类具有父类的特性,提高了代码的重用性。
从设计上是一种增量进化,原有父类设计不变的情况下,可以增加新的功能,或者改进已有的算法。
2.3、多态
多态是指同一个方法调用由于对象不同会产生不同的行为。生活中这样的例子比比皆是:同样是休息方法,人不同休息方法不同。张三休息是睡觉,李四休息是玩游戏,程序员休息是“敲几行代码”。
三、继承
3.1、子类扩展父类
继承是面向对象编程的三大特征之一。继承让我们更加容易实现类的扩展。实现代码的重用,不用再重新发明轮子(don’t reinvent wheels)。
如果一个新类继承自一个设计好的类,就直接具备了已有类的特征,就大大降低了工作难度。已有的类,我们称为“父类或者基类”,新的类,我们称为“子类或者派生类”。
3.2、语法格式
Python支持多重继承,一个子类可以继承多个父类。继承的语法格式如下:
class 子类类名(父类1[,父类2,...]):
类体
如果在类定义中没有指定父类,则默认父类是
object类
。也就是说,object
是所有类的父类,里面定义了一些所有类共有的默认实现,比如:__new__()
关于构造函数:
- 子类不重写
__init__
,实例化子类时,会自动调用父类定义的__init__
。 - 子类重写了
__init__
时,实例化子类,就不会调用父类已经定义的__init__
- 如果重写了
__init__
时,要使用父类的构造方法,可以使用super
关键字,也可以使用如下格式调用:
父类名.__init__(self, 参数列表)
class Person:
def __init__(self,name,age):
print("Person的构造方法")
self.name = name
self.age = age
def say_age(self):
print(self.name,"的年龄是:",self.age)
class Student(Person):
def __init__(self,name,age,score):
# 子类并不会自动调用父类的__init__(),我们必须显式的调用它。
# Person.__init__(self, name, age)
# super(Student,self).__init__(name,age)
print("Student的构造方法")
# self.name = name
# self.age = age
self.score = score
s1 = Student("张三",15,85)
#s1.say_age()
print(dir(s1))
运行结果:
张三 的年龄是: 15
['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'say_age', 'score']
四、类成员的继承和重写
-
成员继承:子类继承了父类除构造方法之外的所有成员。
⚠️(私有属性、私有方法也被继承)
-
方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为“重写”
【操作】继承和重写的案例
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def say_age(self):
print(self.name,"的年龄是:",self.age)
def say_name(self):
print("我是",self.name)
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age)
self.score = score
def say_score(self):
print(self.name,"的分数是:",self.score)
def say_name(self): #重写父类的方法
print("报告老师,我是",self.name)
s1 = Student("张三",15,85)
s1.say_score()
s1.say_name()
s1.say_age()
执行结果:
张三 的分数是: 85
报告老师,我是 张三
张三 的年龄是: 15
4.1、查看类的继承层次结构
通过类的方法mro()
或者类的属性__mro__
可以输出这个类的继承层次结构。
【操作】 查看类的继承层次结构
class A:pass
class B(A):pass
class C(B):pass
print(C.mro())
执行结果:
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]