知行编程网知行编程网  2022-12-20 14:30 知行编程网 隐藏边栏  4 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于python面试中较常问及的知识点梳理---高级特性的相关知识,希望可以帮到处于编程学习途中的小伙伴

python面试常问知识点梳理---进阶特性

python的高级特性

1.函数装饰器有什么作用?请列举说明?

2. Python 垃圾回收机制?

3. 魔法函数 _call_怎么使用?

4. 如何判断一个对象是函数还是方法?

5. @classmethod 和 @staticmethod 用法和区别

6. Python 中的接口如何实现?

7. Python 中的反射了解么?

8. metaclass 作用?以及应用场景?

9. hasattr()、getattr()、setattr() 的用法

10. 请列举你知道的 Python 的魔法方法及用途。

11. 如何知道一个 Python 对象的类型?

12. Python 的传参是传值还是传址?

13. Python 中的元类 (metaclass) 使用举例

14. 简述 any() 和 all() 方法


1.函数装饰器有什么作用?请列举说明?


答: 装饰器就是一个函数,它可以在不需要做任何代码变动的前提下给一个函数增加额外功能,启动装饰的效果。 它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。 下面是一个日志功能的装饰器

from functools import wraps
def log(label):
    def decorate(func):
       @wraps(func) 
       def _wrap(*args,**kwargs):
        try:
          func(*args,**kwargs)
          print("name",func.__name__)
        except Exception as e:
           print(e.args)
       return _wrap
    return decorate    

@log("info")
def foo(a,b,c):
     print(a+b+c)
     print("in foo")

#decorate=decorate(foo)   

if __name__ == '__main__':
    foo(1,2,3)
     #decorate()


2.Python 垃圾回收机制?

答:与C++、Java等语言不同,Python可以直接给变量赋值,无需事先声明变量类型。对于 Python 语言,对象的类型和内存是在运行时确定的。这就是我们称 Python 语言为动态类型的原因。

主要体现在下面三个方法:

1.引用计数机制 2.标记-清除 3.分代回收


3.魔法函数 _call_怎么使用?

答: call 可以把类实例当做函数调用。 使用示例如下

class Bar:
    def __call__(self, *args, **kwargs):
        print('in call')


if __name__ == '__main__':
    b = Bar()
    b()


4.如何判断一个对象是函数还是方法?


答:看代码及结果就懂了

from types import MethodType, FunctionType

class Bar:
    def foo(self):
        pass

def foo2():
    pass

def run():
    print("foo 是函数", isinstance(Bar().foo, FunctionType))
    print("foo 是方法", isinstance(Bar().foo, MethodType))
    print("foo2 是函数", isinstance(foo2, FunctionType))
    print("foo2 是方法", isinstance(foo2, MethodType))

if __name__ == '__main__':
    run()

输出

foo 是函数 False
foo 是方法 True
foo2 是函数 True
foo2 是方法 False


5.@classmethod 和 @staticmethod 用法和区别

答:

相同点:@staticmethod和@classmethod都可以通过类名直接调用。方法名(),没有实例化一个类。

@classmethod 我们想写一个只在类中运行而不在实例中运行的方法。如果我们不希望该方法在实例中运行,我们可以这样做:

def iget_no_of_instance(ins_obj):
    return ins_obj.__class__.no_inst

class Kls(object):
    no_inst = 0

    def __init__(self):
        Kls.no_inst = Kls.no_inst + 1

ik1 = Kls()
ik2 = Kls()
print(iget_no_of_instance(ik1))

@staticmethod 往往有一些与类相关的功能,但在运行时不需要实例和类的参与时需要使用静态方法:

IND = 'ON'

class Kls(object):
    def __init__(self, data):
        self.data = data

    @staticmethod
    def check_ind():
        return (IND == 'ON')

    def do_reset(self):
        if self.check_ind():
            print('Reset done for:', self.data)

    def set_db(self):
        if self.check_ind():
            self.db = 'New db connection'
        print('DB connection made for: ', self.data)

ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()


6.Python 中的接口如何实现?

答:接口提取了一组类共有的功能。你可以把接口看成是函数的集合,然后让子类去实现接口中的函数。但是在 Python 中根本没有名为 interface 的关键字。如果一定要模仿接口的概念,可以用抽象类来实现。抽象类是一个特殊的类,它的特殊之处在于它只能被继承而不能被实例化。使用 abc 模块实现抽象类。


7.Python 中的反射了解么?

答:Python的反射机制的设置比较简单。有四个关键函数:getattr、hasattr、setattr 和 delattr。


8.metaclass 作用?以及应用场景?

答:元类就是元类。元类是一个类似于创建类的模板。所有的类都是通过他创建的(调用new),可以让你自由控制创建类的过程,实现你需要的功能。我们可以使用元类来创建单例模式并实现 ORM 模式。


9.hasattr()、getattr()、setattr() 的用法

答:这三个方法属于Python的反射机制。 hasattr可以判断一个对象是否包含某个属性,getattr可以充当get获取对象属性。而setattr可以作为person.name = "liming"的赋值操作。代码示例如下:

class Person():
    def __init__(self):
        self.name = "liming"
        self.age = 12

    def show(self):
        print(self.name)
        print(self.age)

    def set_name(self):
        setattr(Person, "sex", "男")

    def get_name(self):
        print(getattr(self, "name"))
        print(getattr(self, "age"))
        print(getattr(self, "sex"))

def run():
    if hasattr(Person, "show"):
        print("判断 Person 类是否含有 show 方法")

    Person().set_name()
    Person().get_name()

if __name__ == '__main__':
    run()


10.请列举你知道的 Python 的魔法方法及用途。



1 __init__:
类的初始化方法。它获取任何传给构造器的参数(比如我们调用 x = SomeClass(10, ‘foo’) , __init__就会接到参数 10 和 
‘foo’ 。 __init__在 Python 的类定义中用的最多。

2 __new__:
__new__是对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__ 。 __new__很少使用,但是也有它适合
的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候.

3 __del__:
__new__和 __init__是对象的构造器, __del__是对象的销毁器。它并非实现了语句 del x (因此该语


11.如何知道一个 Python 对象的类型?

答:可以通过 type 方法


12.Python 的传参是传值还是传址?

答:Python中传递参数既不是传递值也不是传递地址,而是传递对象的引用。


13.Python 中的元类 (metaclass) 使用举例

答:可以使用元类实现一个单例模式,代码如下:

class Singleton(type):
    def __init__(self, *args, **kwargs):
        print("in __init__")
        self.__instance = None
        super(Singleton, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        print("in __call__")
        if self.__instance is None:
            self.__instance = super(Singleton, self).__call__(*args, **kwargs)
        return self.__instance

class Foo(metaclass=Singleton):
    pass  # 在代码执行到这里的时候,元类中的__new__方法和__init__方法其实已经被执行了,而不是在 Foo 实例化的时候执行。
    且仅会执行一次。

foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2)


14.简述 any() 和 all() 方法

答:any(x):判断对象x是否为空对象,如果全为空、0、false则返回false,不全为空、0、false则返回true。 all(x):如果all(x)参数x对象的所有元素都不为0、''、False或x为空对象,则返回True,否则返回False。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享