目录
请用类代码简答实现stack 栈
- Stack() 创建一个新的空栈
- push(item) 添加一个新的元素item到栈顶
- pop() 弹出栈顶元素
- peek() 返回栈顶元素
- is_empty() 判断栈是否为空
- size() 返回栈的元素个数
# 实现一个栈stack,后进先出
'''
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
# 判断是否为空
return self.items == []
def push(self,item):
# 加入元素
self.items.append(item)
def pop(self):
# 弹出元素
return self.items.pop()
def peek(self):
# 返回栈顶元素
return self.items[len(self.items)-1]
def size(self):
# 返回栈的大小
return len(self.items)
if __name__ == "__main__":
stack = Stack()
stack.push("H")
stack.push("E")
stack.push("L")
print(stack.size()) # 3
print(stack.peek()) # L
print(stack.pop()) # L
print(stack.pop()) # E
print(stack.pop()) # H
'''
谈谈你对面向对象的理解
三大特性以及解释?
面对对象是一种编程思想,以类的眼光来来看待事物的一种方式。将有共同的属性和方法的事物封装到同一个类下面。
继承:将多个类的共同属性和方法封装到一个父类下面,然后在用这些类来继承这个类的属性和方法
封装:将有共同的属性和方法封装到同一个类下面
- 第一层面:创建类和对象会分别创建二者的名称空间,我们只能用类名.或者obj.的方式去访问里面的名字,这本身就是一种封装
- 第二层面:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用、外部无法访问,或者留下少量接口(函数)供外部访问。
多态:Python天生是支持多态的。指的是基类的同一个方法在不同的派生类中有着不同的功能
Python面向对象中的继承有什么特点
python 两种类:经典类 新式类
python3 新式类 —— 都默认继承object class Animal(object): == class Animal:
python2 经典类和新式类 并存
class Animal: 经典类 —— 继承顺序 个别使用方法
class Animal(object): 新式类
继承分为单继承和多继承
Python是支持多继承的
如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
1、对象可以调用自己本类和父类的所有方法和属性, 先调用自己的 自己没有才调父类的。谁(对象)调用方法,方法中的self就指向谁
class Foo:
def __init__(self):
self.func()
def func(self):
print('Foo.func')
class Son(Foo):
def func(self):
print('Son.func')
面向对象深度优先和广度优先是什么?
Python的类可以继承多个类,Python的类如果继承了多个类,那么其寻找方法的方式有两种
当类是经典类时,多继承情况下,会按照深度优先方式查找 py3
当类是新式类时,多继承情况下,会按照广度优先方式查找 py2
简单点说就是:经典类是纵向查找,新式类是横向查找
经典类和新式类的区别就是,在声明类的时候,新式类需要加上object关键字。在python3中默认全是新式类
面向对象中super的作用?
用于子类继承基类的方法
class FooParent(object):
def __init__(self):
self.parent = 'I\'m the parent.'
print('Parent')
print('1111')
def bar(self, message):
print("%s from Parent" % message)
class FooChild(FooParent):
def __init__(self):
# super(FooChild,self) 首先找到 FooChild 的父类(就是类 FooParent),然后把类B的对象 FooChild 转换为类 FooParent 的对象
super(FooChild, self).__init__()
print('Child')
# def bar(self, message):
# # super(FooChild, self).bar(message)
# print('Child bar fuction')
# print(self.parent)
if __name__ == '__main__':
fooChild = FooChild()
fooChild.bar('HelloWorld')
列举面向对象中带双下划线的特殊方法,如:new、init
__new__:生成实例
__init__:生成实例的属性
__call__:实例对象加( )会执行def __call__:... 方法里边的内容。
__del__:析构方法,当对象在内存中被释放时,自动触发执行。如当 del obj 或者应用程序运行完毕时,执行该方法里边的内容。
__enter__和__exit__:出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量;with中代码块执行完毕时执行__exit__里边的内容。
__module__:表示当前操作的对象在那个模块 obj.__module__
__class__ :表示当前操作的对象的类是什么 obj.__class__
__doc__:类的描述信息,该描述信息无法被继承
__str__:改变对象的字符串显示 print函数 --->obj.__str__()
__repr__:改变对象的字符串显示 交互式解释器 --->obj.__repr__()
__format__:自定制格式化字符串
__slots__:一个类变量 用来限制实例可以添加的属性的数量和类型
__setitem__,__getitem,__delitem__:
如何判断是函数还是方法?
看他的调用者是谁,如果是类,就需要传入一个参数self的值,这时他就是一个函数,
如果调用者是对象,就不需要给self传入参数值,这时他就是一个方法
print(isinstance(obj.func, FunctionType)) # False
print(isinstance(obj.func, MethodType)) # True
函数:
函数是封装了一些独立的功能,可以直接调用,python内置了许多函数,同时可以自建函数来使用。
方法:
方法和函数类似,同样封装了独立的功能,但是方法是需要通过对象来调用的,表示针对这个对象要做的操作,使用时采用点方法。
静态方法和类方法区别?
尽管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明显的区别。classmethod 必须有一个指向类对象的引用作为第一个参数,而 staticmethod 可以没有任何参数。
class Num:
# 普通方法:能用Num调用而不能用实例化对象调用
def one():
print ('1')
# 实例方法:能用实例化对象调用而不能用Num调用
def two(self):
print ('2')
# 静态方法:能用Num和实例化对象调用
@staticmethod
def three():
print ('3')
# 类方法:第一个参数cls长什么样不重要,都是指Num类本身,调用时将Num类作为对象隐式地传入方法
@classmethod
def go(cls):
cls.three()
Num.one() #1
#Num.two() #TypeError: two() missing 1 required positional argument: 'self'
Num.three() #3
Num.go() #3
i=Num()
#i.one() #TypeError: one() takes 0 positional arguments but 1 was given
i.two() #2
i.three() #3
i.go() #3
列举面向对象中的特殊成员以及应用场景
__call__
__new__
__init__
__doc__
__class__
__del__
__dict__
__str__
在falsk源码用到......
什么是反射?以及应用场景?
反射的核心本质就是以字符串的形式去导入个模块,利用字符串的形式去执行函数。
Django中的 CBV就是基于反射实现的。
4个方法
getattr、hasattr、delattr和setattr较为全面的实现了基于字符串的反射机制
metaclass作用?以及应用场景?
不知道
class MyType(type):
def __call__(self, *args, **kwargs):
return 'MyType'
class Foo(object, metaclass=MyType):
def __init__(self):
return 'init'
def __new__(cls, *args, **kwargs):
return cls.__init__(cls)
def __call__(self, *args, **kwargs):
return 'call'
obj = Foo()
print(obj) # MyType
用尽量多的方法实现单例模式。
1:使用模块
Python的模块就是天然的单例模式。
因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。
因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
例如:
class V1(object):
def foo(self)
pass
V1 = V1()
将上面代码保存在文件test.py,要使用时,直接在其他文件中导入此文件中的对象,这个对象既是单例模式的对象
如:from a import V1
2:使用装饰器
def Singleton(cls):
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a = 1
def __init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)
3:使用类
4:基于__new__方法实现
当我们实例化一个对象时,是先执行了类的__new__方法
当:(我们没写时,默认调用object.__new__),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式
什么是面向对象的mro
mro就是方法解析顺序
super 继承都用到
isinstance作用以及应用场景?
isinstance(对象,类) 判断这个对象是不是这个类或者这个类的子类的实例化
# # 判断a 属不属于A这个类(可以判断到祖宗类)
class A:
pass
class B(A):
pass
a = A()
b = B()
print(isinstance(b,A)) # ===> True 判断到祖宗类
# 任何与object都是True,内部都继承object
class A:pass
a = A() # 实例化
print(isinstance(a,object)) # True
什么是断言?应用场景?
ssert 是的作用?断言
条件成立(布尔值为True)则继续往下,否则跑出异常,一般用于:满足某个条件之后,才能执行,否则应该跑出异常。
写API的时候,继承GenericAPIView
class GenericAPIView(views.APIView):
"""
Base class for all other generic views.
"""
# You'll need to either set these attributes,
# or override `get_queryset()`/`get_serializer_class()`.
# If you are overriding a view method, it is important that you call
# `get_queryset()` instead of accessing the `queryset` property directly,
# as `queryset` will get evaluated only once, and those results are cached
# for all subsequent requests.
queryset = None
serializer_class = None
# If you want to use object lookups other than pk, set 'lookup_field'.
# For more complex lookup requirements override `get_object()`.
lookup_field = 'pk'
lookup_url_kwarg = None
# The filter backend classes to use for queryset filtering
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
# The style to use for queryset pagination.
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get_queryset(self):
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset