python常见的面试题,python面试基础题目
0x00前言类,在学习面向对象中我们可以把类看成一个规范。从我个人的经历来看,这个想法很重要。除了封装的函数,类是一个我们可以自定义的规范。从这个角度来说,对我们以后学习设计模式的时候理解设计模式会有很大的帮助。其次,语言中的类是抽象模板,用来描述具有相同属性和方法的对象集合,比如动物类。实例是根据类创建的具体“对象”。每个对象都有相同的方法,但其数据可能不同。
使用Python class关键字定义一个类,其基本结构如下:
类名(父类列表):
及格
类名通常采用驼峰式命名,这样字面意思就能尽可能反映出类的功能。Python采用多重继承机制,一个类可以同时继承多个父类(也叫基类和超类)。继承的基类是有序的,写在类名后面的括号中。继承的父类列表可以为空,括号可以省略。但是,在Python3中,即使你采用了classStudent:pass这样的方法定义了一个类,而没有显式继承任何父类,默认情况下,它也会继承object类。因为object是Python3中所有类的基类。
以下是一节学生课:
班级学生:
教室=101
地址=北京
def __init__(自己,姓名,年龄):
self.name=name
年龄=年龄
定义打印年龄(自己):
Print (%s:% s% (self.name,self.age))可以通过调用类的实例化方法(在某些语言中也称为初始化方法或构造函数)来创建类的实例。默认情况下,您可以通过使用obj=Student()之类的东西来生成一个类的实例。然而,通常一个类的每个实例都有自己的实例变量,比如这里的name和age。为了体现实例化时实例的差异,Python提供了def__init__(self)的实例化机制。在任何类中,名为__init__的方法都是该类的实例化方法。当带有__init__方法的类被实例化时,它会自动调用该方法并传递相应的参数。例如:
班级学生:
李=学生(“李四”,24)
张=学生(“张三”,23)
0x01实例变量和类变量实例变量:实例变量是指实例本身拥有的变量。每个实例的变量在内存中是不同的。Student类的__init__方法中的name和age是两个实例变量。通过在实例名中添加点来调用实例变量。
我们打印以下四个变量,我们可以看到,虽然每个实例的变量名相同,但它们保存的值是相互独立的:
打印(李.姓名)
打印(李.时代)
打印(张.姓名)
打印(张.时代)
-
李四
24
张三
23
类:定义在类中而不是方法中的变量称为类变量。类变量是所有实例共有的,每个实例都可以访问和修改类变量。在学生类中,教室和地址这两个变量是类变量。您可以通过在类名或实例名中添加点来访问类变量,例如:
学生.教室
学生.地址
李教室
张. address在使用实例变量和类变量的时候,一定要注意。在访问张. name这样的变量时,实例会先查找自己的实例变量列表中是否有这个实例变量。如果没有,那么它将在类变量列表中查找。否则,将弹出一个异常。
Python动态语言的特性允许我们随时向实例添加新的实例变量,向类添加新的类变量和方法。因此,当使用li.classroom=102 时,要么重新分配现有的实例变量classroom,要么创建一个专属于li的新实例变量classroom并将其分配给 102 。看下面这个例子。
Class Student: #类的定义体
Classroom=101 # class变量
地址=北京
def __init__(自己,姓名,年龄):
self.name=name
年龄=年龄
定义打印年龄(自己):
打印( %s: %s % (self.name,self.age))
李=学生(李四,24) #创建一个实例
张=学生(《张三》,23) #创建第二个实例
Li.classroom # li本身没有classroom实例变量,所以找一个class变量,它就找到了!
101
张的教室号和李的一样
101
Student.classroom #通过类名访问类变量
101
关键的一步!实际上,为li创建了一个唯一的实例变量,但名称与类变量相同,称为classroom。
当李. classroom #再次访问时,是李自己的实例变量教室。
102
Zhang.classroom # zhang没有实例变量classroom,但仍然访问类变量classroom。
101
学生.教室#保持不变。
101
Del li.classroom #删除了李的实例变量教室
李. classroom #一切又恢复了原状。
101
张教室
101
学生.教室
101
0x03类方法Python的类包含三种方法:实例方法、静态方法和类方法。这些方法都属于类,不管是在代码排列上还是在内存上,区别就是传入的参数和调用的方法不一样。在类内部,使用def关键字定义一个方法。
实例类的实例方法由实例调用,包含至少一个self参数,这是第一个参数。当执行实例方法时,调用该方法的实例被自动分配给self。Self表示一个类的实例,而不是类本身。不是关键字self,而是Python中习惯性的命名。可以取别的名字,但不推荐。
比如我们之前学生班的print_age()就是实例方法:
定义打印年龄(自己):
打印( %s: %s % (self.name,self.age))
# -
#调用方法
李. print_age()
张. print_age()
方法静态方法由类调用,没有默认参数。从实例方法参数中移除self,然后在方法定义上方添加@staticmethod,这就变成了一个静态方法。它属于类,与实例无关。建议只使用类名。静态方法的调用方法。(虽然也可以用实例名调用。静态方法)
Foo类:
@静态方法
def静态方法():
及格
#调用方法
Foo .静态方法()
Class method类方法由类调用,用@classmethod修饰,至少传入一个cls(类本身,类似于self)参数。当执行类方法时,调用该方法的类会自动分配给cls。建议只使用类名。类方法的调用方法。(虽然也可以用实例名调用。类方法)
Foo类:
@classmethod
定义class_method(cls):
及格
Foo.class_method()
看一个综合的例子:
Foo类:
def __init__(self,name):
self.name=name
def ord_func(self):
用至少一个自身参数定义实例方法
打印(“实例方法”)
@classmethod
def class_func(cls):
定义至少有一个cls参数的类别方法
打印(“类方法”)
@静态方法
def static_func():
定义了一个没有默认参数的静态方法
打印(“静态方法”)
#调用实例方法
f=Foo(Jack )
函数函数()
O.ord _ func (f) #请注意这种称呼方式。虽然可行,但不建议这么做!
#调用类方法
Foo.class_func()
F.class_func() #请注意这种调用方式。虽然可行,但不建议这么做!
#调用静态方法
Foo.static_func()
F.static_func() #请注意这种调用方式。虽然可行,但不建议这么做!
0x04类、类方法、类变量、类的实例以及实例变量如何保存在内存中。内存中只有一个class、所有方法和类变量的副本,所有实例共享它们。并且每个实例独立地将自己及其实例变量保存在内存中。
创建实例时,除了封装实例变量(如名称和年龄)之外,实例中还保存了一个类对象指针,指向实例所属类的地址。因此,实例可以找到自己的类并进行相关调用,但类找不到自己的实例之一。
0x 05 Python类的继承在ptyhon中,一个类可以同时继承多个类。语法:
类名(父类1,父类2,)
类似物体
类继承的深度优先Python支持多重继承,但多重继承的搜索顺序与经典类和新类不同。
经典:
P1等级:
def foo(自身):
打印“p1-foo”
P2等级:
def foo(自身):
打印 p2-foo
定义栏(自身):
打印 p2栏
C1级(P1,P2):
及格
C2级(P1,P2):
定义栏(自身):
打印 C2酒吧
D级(C2 C1):
pass的实例D调用foo()时,搜索顺序是D=C1=P1
当D实例调用bar()时,搜索顺序是D=C1=P1=P2。
换句话说,经典类的搜索方法是以“从左到右,深度优先”的方式查找属性。d首先,弄清楚本身是否有foo方法。如果没有foo方法,找出最近的父类C1中是否有这个方法。如果没有foo方法,继续向上搜索,直到在P1找到该方法,搜索结束。
Python类继承的广度优先。
新类别:
P1类(对象):
def foo(自身):
打印“p1-foo”
P2类(对象):
def foo(自身):
打印 p2-foo
定义栏(自身):
打印 p2栏
C1级(P1,P2):
及格
C2级(P1,P2):
定义栏(自身):
打印 C2酒吧
D级(C2 C1):
pass的实例D调用foo()时,搜索顺序是D=C1=C2=P1
当D实例调用bar()时,搜索顺序是D=C1=C2。
可以看出,新类的搜索方法是使用“广度优先”来查找属性。
涉及
转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。