每日Python面试题(十一)

138 阅读3分钟

各位看官老爷👵👴,咱们今天要聊的,是三个Python面试里老常见的问题👨‍💻。首先,classmethodstaticmethod的区别是啥?接着,__new____init__有什么不同?最后,啥叫元类(metaclass)?咱作为一位资深的Python开发者,用最简单的方式给您细细道来。

classmethodstaticmethod区别?

在Python中,classmethodstaticmethod都是用来定义类中的方法,但它们之间有着本质的区别。

classmethod是指可以通过类直接调用的方法。这种方法的第一个参数是类本身,而不是类的实例。这个参数通常命名为clsclassmethod的一个常用场景是定义工厂方法,这些方法可以返回类的对象。由于classmethod接收的是类引用,所以可以访问类变量,但无法访问实例变量。

class A:
    @classmethod
    def example_classmethod(cls):
        print(f"调用了{cls}的类方法")

staticmethod,顾名思义,就是静态方法。它既不需要类引用也不需要实例引用。静态方法是一种普通函数,只是恰好在类的代码块中定义。它的用途主要是组织代码,使得与类相关的函数可以归类管理,但它们不需要访问类或实例的任何属性。

class B:
    @staticmethod
    def example_staticmethod():
        print("调用了静态方法")

两者的主要区别在于,classmethod需要接收类作为第一个参数,而staticmethod则不接收类或实例作为参数。

__new____init__区别?

__new____init__是Python中创建和初始化新对象时用到的两个魔术方法,它们扮演着不同的角色。

__new__是一个静态方法,负责创建对象,并返回对象实例,这发生在__init__之前。__new__方法的第一个参数是cls,代表要实例化的类。这个方法可以返回其他类的实例,也可以返回其类的实例,当创建的是当前类的实例时,接下来会调用__init__方法。

class C:
    def __new__(cls):
        print("创建对象")
        return super().__new__(cls)

__init__方法用于初始化创建好的对象。__init__并不返回任何值,它只是对新创建的对象进行初始化。__init__方法接收的第一个参数是self,即对象本身。

class D:
    def __init__(self):
        print("初始化对象")

简而言之,__new__负责创建对象,__init__负责初始化对象。

什么是元类?

元类(metaclass)是类的类,即创建类的东西。在Python中,类定义了如何创建对象,而元类定义了如何创建类。使用元类可以控制类的创建过程。

Python中的一切都是对象,包括整数、字符串、函数甚至类。Python中的类是type类的实例。所以,type是大多数内建的元类,用来创建所有的类。

元类的使用场景包括:创建带有特定属性的类、修改类的属性等。虽然在日常开发中不常用,但理解元类的概念有助于深入理解Python的对象模型。

def upper_attr(future_class_name, future_class_parents, future_class_attr):
    uppercase_attr = {}
    for name, val in future_class_attr.items():
        if not name.startswith('__'):
            uppercase_attr[name.upper()] = val
        else:
            uppercase_attr[name] = val
    return type(future_class_name, future_class_parents, uppercase_attr)

class E(metaclass=upper_attr):
    bar = 'bip'

启发和启示

了解classmethodstaticmethod的区别,有助于在设计类时更合理地组织代码,提高代码的可读性和维护性。掌握__new____init__的用法,可以让开发者更灵活地控制对象的创建和初始化过程。元类的概念虽然抽象,但它打开了Python深度定制类行为的大门,使得Python在灵活性和动态性方面更加强大。

所以,深入理解这些高级特性,对于提升开发者的编程技能、拓宽编程视野有着重要的意义🚀。在日常开发中虽不常用,但一旦需要,将是解决问题的利器。