面向对象面试题11-20

有用过with statement(语句)吗?它的好处是什么?

# 答案
'''
with语句会在嵌套的代码执行之后,自动关闭文件。这种做法的还有另一个优势就是,无论嵌套的代码是以何种方式结束的,它都关闭文件。如果在嵌套的代码中发生异常,它能够在外部exception handler catch异常前关闭文件。如果嵌套代码有return/continue/break语句,它同样能够关闭文件。
'''

下列数据结构中,哪一种是不可迭代的

'''
    A.  dict
    B.  object
    C.  set
    D.  str
'''

# 答案:
B

实现一个Singleton单例类,要求遵循基本语言编程规范(用尽量多的方 式)。

# 答案:
1.__new__
class Borg(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            ob = super(Borg, cls)
            cls._instance = ob.__new__(cls, *args, **kwargs)
        return cls._instance
class MyClass(Borg):
    def __init__(self):
        self.a = 1
        
2.共享属性
class Borg2(object):
    _state = {}

    def __new__(cls, *args, **kwargs):
        ob = super(Borg2, cls).__new__(cls, *args, **kwargs)
        ob.__dict__ = cls._state
        return ob

class MyClass(Borg2):
    def __init__(self):
        self.a = 1
        
3.装饰器
def singleton(cls, *args, **kwargs):
    instances = {}

    def getinstance():
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return getinstance

@singleton
class MyClass(object):
    def __init__(self):
        self.a = 1

4.import方法
# mysingleton .py
class MyClass(object):
    def __init__(self):
        self.a = 1

s_myclass = MyClass()

from mysingleton import s_myclass

s_myclass.a

请口述with的用法,如果自己的类需要支持with语句,应该如何书写?

基本格式
with context_expression [as target(s)]:
    with-body
'''
这里 context_expression 要返回一个上下文管理器对象,该对象并不赋值给 as 子句中的 target(s) ,如果指定了 as 子句的话,会将上下文管理器的 __enter__() 方法的返回值赋值给 target(s)。
target(s) 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)。

自定义的上下文管理器要实现上下文管理协议所需要的 __enter__() 和 __exit__() 两个方法
context_manager.__enter__() :进入上下文管理器的运行时上下文,在语句体执行前调用。with 语句将该方法的返回值赋值给 as 子句中的 target,如果指定了 as 子句的话
context_manager.__exit__(exc_type, exc_value, exc_traceback) :退出与上下文管理器相关的运行时上下文,返回一个布尔值表示是否对发生的异常进行处理。
'''

python 中如何判断一个对象是否可调用? 哪些对象可以是可调用对象?如何定义一个类,使其对象本身就是可调用对象?

# 答案:
# python 中如何判断一个对象是否可调用
def func():
    pass
print(callable(func))  # True

# 哪些对象可以是可调用对象
1.类对象
2.所有带有_call_()方法的对象

# 如何定义一个类,使其对象本身就是可调用对象
一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法call()。

请实现一个栈。

# 答案:
class Stack(object) :
  def __init__(self,size):
    #类的构造函数
    self.size = size
    self.stack = []

  def __str__(self):
    #类的字符串输出方法,类似于java的.toString()方法
    return str(self.stack)

  def getSize(self) :
    #获取栈当前大小
    return len(self.stack)

  def push(self, x) :
    #入栈,栈满抛异常
    if self.isfull() :
      #return -1
      raise Exception("Stack is full")
    self.stack.append(x)

  def pop(self) :
    #出栈,栈空抛异常
    if self.isempty() :
      #return -1
      raise Exception("Stack is empty")
    topElement = self.stack[-1] 
    self.stack.remove(topElement)
    return topElement

  def isempty(self) :
    #判断栈空
    if len(self.stack) == 0 :
      return True
    return False

  def isfull(self) :
    #判断栈满
    if len(self.stack) == self.size :
      return True
    return False

关于Python类的继承不正确的说法是?(多选)

 A. Python类无法继承
 B. 可以继承, 无法执行父类的构造函数 
 C. 可以有多个父类
 D. 只能有一个父类 
 
 # 答案
 '''
 A
 D
 '''

实现一个hashtable类,对外暴露的有add和get方法,满足以下测试代码

def test():
    import uuid
    names = {"name", "web", "python"}
    ht = HashTable()
    for key in names:
        value = uuid.uuid4()
        ht.add(key, value)
        print("add 元素", key, value)
    for key in names:
        v = ht.get(key)
        print("get 元素", key, v)
 
# 答案:
class HashMap(object):
     def __init__(self):
         # 初始化总表为,容量为2的表格(含两个子表)
         self.maps = BetterMap(2)
         self.num = 0        # 表中数据个数
     
     def get(self,k):        
         return self.maps.get(k)
    
     def add(self, k, v):
         # 若当前元素数量达到临界值(子表总数)时,进行重排操作
         # 对总表进行扩张,增加子表的个数为当前元素个数的两倍!
         if self.num == len(self.maps.maps): 
             self.resize()
         
         # 往重排过后的 self.map 添加新的元素
         self.maps.add(k, v)
         self.num += 1
         
     def resize(self):
         """ 重排操作,添加新表, 注意重排需要线性的时间 """
         # 先建立一个新的表,子表数 = 2 * 元素个数
         new_maps = BetterMap(self.num * 2)
         
         for m in self.maps.maps:  # 检索每个旧的子表
             for k,v in m.items:   # 将子表的元素复制到新子表
                 new_maps.add(k, v)
         
         self.maps = new_maps      # 令当前的表为新表

请用两个队列来实现一个栈(给出伪代码即可)

# 答案:
class StackWithTwoQueues(object):
    #定义两个空队列
    def __init__(self):
        self.queue1 = []
        self.queue2 = []
    #入栈
    def push(self, item):
        self.queue1.append(item)
    #出栈
    def pop(self):
        if len(self.queue1) == 0:
            return(None)
        while(len(self.queue1) != 1):
            self.queue2.append(self.queue1.pop(0))
        self.queue1, self.queue2 = self.queue2, self.queue1
        return (self.queue2.pop())
#test
if __name__ == '__main__':
    ss = StackWithTwoQueues()
    list = [0, 1, 2, 3, 4]
    for i in range(5):
        ss.push(list[i])
    print(list)
    for i in range(5):
        print(ss.pop(), ',', end = '')
#output
#[0, 1, 2, 3, 4]
#4, 3, 2, 1, 0

已知如下链表类,请实现单链表逆置

class Node:
    def __init__(self, value, next):
        self.value = value
        self.next = next

# 答案:
class Solution:
    def ReverseList(self, pHead):
        if not pHead or not pHead.next:
            return pHead
          
        last = None
          
        while pHead:
            tmp = pHead.next
            pHead.next = last
            last = pHead
            pHead = tmp
        return last
posted @ 2019-12-12 20:53  極9527  阅读(232)  评论(0编辑  收藏  举报