【python面试指北】3.类和面向对象

2019-11-10  本文已影响0人  知鱼君

面向对象编程

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def print_name(self):
        print self.name

组合与继承

优先使用组合(has a)而非继承(is a)

类变量和实例变量的区别

classmethod/staticmethod区别

class Person(object):
    Country = 'china'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def print_name(self):
        print self.name

    @classmethod
    def print_country(cls):
        print(cls.Country)

    @staticmethod
    def join_name(first_name, last_name):
        return last_name + first_name

什么是元类

元类是创建类的类

例子:

装饰器

import time
def log_time(func): # 接受一个函数作为参数
    def _log(*args, **kwargs):
        beg = time.time()
        res = func(*args, **kwargs)
        print('use time: {}'.format(time.time()-beg))
        return res
    return _log

@log_time   # 装饰器语法糖
def mysleep():
    time.sleep(1)

mysleep()

# 另一种写法

def mysleep2():
    time.sleep(1)

newsleep = log_time(mysleep2)
newsleep()

使用类编写装饰器

import time
class LogTime:
    def __call__(slef, func): # 接受一个函数作为参数
        def _log(*args, **kwargs):
            beg = time.time()
            res = func(*args, **kwargs)
            print('use time: {}'.format(time.time()-beg))
            return res
        return _log

@LogTime()
def mysleep():
    time.sleep(1)

mysleep()

如何给装饰器增加参数?使用类转时期比较方便实现装饰器参数

import time
class LogTime:
    def __init__(self, use_int=False):
        self.use_int = use_int

    def __call__(slef, func): # 接受一个函数作为参数
        def _log(*args, **kwargs):
            beg = time.time()
            res = func(*args, **kwargs)
            if self.use_int:
                print('use time: {}'.format(int(time.time()-beg)))
            else:
                print('use time: {}'.format(time.time()-beg))
            return res
        return _log

@LogTime(True)
def mysleep():
    time.sleep(1)

mysleep()

设计模式

学习设计模式的一个有效的方式是自己尝试写个示例代码来演示它

创建型

工厂模式

class DogToy:
    def speak(self):
        print("wang wang")

class CatToy:
    def speak(self):
        print("miao miao")

def toy_factory(toy_type):
    if toy_type == 'dog':
        return DogToy()
    elif toy_type == 'cat':
        return CatToy()

构造模式

原型模式

单例模式

class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            _instance = super().__new__(cls, *args, **kwargs)
            cls._instance = _instance
        return cls._instance

class MyClass(Singleton):
    pass

c1 = MyClass()
c2 = MyClass()
c1 is c2 # true

结构型

代理模式

适配器模式

行为型

迭代器模式

观察者模式

策略模式

函数式编程

map/reduce/filter

reduce(lambda x, y: x+y, range(1,6))

闭包

from functools import wraps

def cache(func):
    store = {}
    @wraps(func)
    def _(n):
        if n in store:
            return store[n]
        else:
            res = func(n)
            store[n] = res
            return res
    return _

@cache
def f(n):
    if n <= 1:
        return 1
    return f(n-1) + f(n-2)

为什么用@wraps(func)

因为当使用装饰器装饰一个函数时,函数本身就已经是一个新的函数;即函数名称或属性产生了变化。所以在python的functools模块中提供了wraps装饰函数来确保原函数在使用装饰器时不改变自身的函数名及应有属性。
所以在装饰器的编写中建议加入wraps确保被装饰的函数不会因装饰器带来异常情况。
https://blog.csdn.net/yuyexiaohan/article/details/82860807

上一篇 下一篇

猜你喜欢

热点阅读