通常这种方法的第一个参数被命名为 'mcs'
Usually first parameter of such methods is named 'mcs'
我在以下元类中收到了一个令人惊讶的 PyCharm 警告
Usually first parameter of such methods is named 'mcs'
这是我不知道的约定,例如将第一个参数命名为 self
或 cls
?我尝试搜索 SO 但没有找到任何结果。代码取自 this post.
class Meta(type):
def __prepare__(metaclass, cls, bases):
return dict()
def __new__(metacls, cls, bases, clsdict):
return super().__new__(metacls, cls, bases, clsdict)
对于 metaclasses,通常是“class 方法”的方法 - 如 __prepare__
和 __new__
将在第一个参数上接收 metaclass本身。
没有关于该参数命名的约定。通常人们不知道,或者根本不担心元 class 真正发生的事情的全部范围,会简单地将这些 cls
命名为正常的 class 和生活如下。我相信大多数 IDE 不会识别其他任何东西,如果突出显示“正确”使用“cls”和“self”作为方法的第一个参数,它们甚至可能将其他任何东西标记为“错误”。人们必须始终牢记这些只是约定 - 短绒和语法高亮器远不如人类思维灵活(至少目前如此),他们的话不应被视为法律。
也就是说,与名称“cls”和“self”不同,第一个参数何时是元class本身没有严格的约定——我通常将其命名为mcls
,但是mcs
没问题,而 metaclass
有点危险,因为它是 class 定义本身的保留关键字(使用 class
语句时)。
但是,碰巧 metaclass
参数中使用的 class 恰好是传递给 meta[=90] 的第一个参数的那个=] __new__
方法,所以,是的,如果元 class __new__
中的第一个参数被命名为 metaclass
,它可能会“修复不一致”。 (我从没想过)。
换句话说,当用 class MyClass(ClassA, ClassB, metaclass=MyMeta):
定义 class 时,MyMeta
是 MyMeta.__new__
的第一个参数中传递的内容,如果它被命名metaclass
,这将是 ,就好像 Python 将其作为“命名参数”传递一样。即使在 class
语句一侧,metaclass
名称在语言定义中是硬编码的,而在 def __new__
一侧,将使用第一个参数中的任何名称。
In [98]: class M(type):
...: def __new__(metaclass, name, bases, namespace, **kwargs):
...: return super().__new__(metaclass, name, bases, namespace, **kwargs)
...:
In [99]: class A(metaclass=M):
...: pass
不管怎样,正如我所说,我通常对mcls
感到满意。
相反,同样重要的是:metaclass 上的任何其他方法,在普通 class 上将是 self
的任何其他方法都将作为参数接收 class
使用 metaclass 创建 - 因此通常将这些命名为 cls
而不是 self
,因为这样更容易记住 metaclass 的实例是什么代表.
因此,在方法 __init__
、__getattr__
、__call__
的元 class 中以及任何认为有用的方法中,第一个参数是 cls
而不是 self
.
回到你的一个片段:
class Meta(type):
def __prepare__(metaclass, cls, bases):
return dict()
def __new__(metacls, cls, bases, clsdict):
return super().__new__(metacls, cls, bases, clsdict)
正如我评论的那样,您可以调用第一个参数 metacls
,但是 __new__
和 __prepare__
的 第二个 参数应该是 name
不是 cls
。再次:Python 将这些作为有序参数传递,因此如果您将其命名为 cls
,它将 工作 ,但其内容是声明的 class 名称尽管如此,还是一个字符串。一方面,cls
名称通常指定 class 本身,当调用这些方法时它甚至 不存在 - 它只会从点存在在 __new__
metaclass 方法中调用 super().__new__
的地方。
至于第四个参数,你调用 clsdict
,我知道没有强约定 - clsdict
足够清楚,namespace
- 但多年来,我一直简单地使用 dct
,有时也使用 ns
。
最后,如上所述,我不希望 PyCharm 或任何其他样式荧光笔(或“校正器”)比我更了解我对 metaclass 的意图:我会忽略它们。
我认为 meta类 的使用频率比常规 类 低得多,因此像 self
和 cls
这样强大和广泛的约定不合乎逻辑不存在。
Google 搜索结果稍微偏向 mcs
:
__new__(mcs
3490 个结果
__new__(mcls
2230 个结果
__new__(metacls
1940 个结果
__new__(metaclass
919 个结果
就我个人而言,我会倾向于 metacls
,因为它更具描述性,而且对我来说感觉更符合 cls
。
可以在 File | Settings | Editor | Inspections | Python | Methods having troubles with first parameter
中更改首选值,请参阅屏幕截图:
我在以下元类中收到了一个令人惊讶的 PyCharm 警告
Usually first parameter of such methods is named 'mcs'
这是我不知道的约定,例如将第一个参数命名为 self
或 cls
?我尝试搜索 SO 但没有找到任何结果。代码取自 this post.
class Meta(type):
def __prepare__(metaclass, cls, bases):
return dict()
def __new__(metacls, cls, bases, clsdict):
return super().__new__(metacls, cls, bases, clsdict)
对于 metaclasses,通常是“class 方法”的方法 - 如 __prepare__
和 __new__
将在第一个参数上接收 metaclass本身。
没有关于该参数命名的约定。通常人们不知道,或者根本不担心元 class 真正发生的事情的全部范围,会简单地将这些 cls
命名为正常的 class 和生活如下。我相信大多数 IDE 不会识别其他任何东西,如果突出显示“正确”使用“cls”和“self”作为方法的第一个参数,它们甚至可能将其他任何东西标记为“错误”。人们必须始终牢记这些只是约定 - 短绒和语法高亮器远不如人类思维灵活(至少目前如此),他们的话不应被视为法律。
也就是说,与名称“cls”和“self”不同,第一个参数何时是元class本身没有严格的约定——我通常将其命名为mcls
,但是mcs
没问题,而 metaclass
有点危险,因为它是 class 定义本身的保留关键字(使用 class
语句时)。
但是,碰巧 metaclass
参数中使用的 class 恰好是传递给 meta[=90] 的第一个参数的那个=] __new__
方法,所以,是的,如果元 class __new__
中的第一个参数被命名为 metaclass
,它可能会“修复不一致”。 (我从没想过)。
换句话说,当用 class MyClass(ClassA, ClassB, metaclass=MyMeta):
定义 class 时,MyMeta
是 MyMeta.__new__
的第一个参数中传递的内容,如果它被命名metaclass
,这将是 ,就好像 Python 将其作为“命名参数”传递一样。即使在 class
语句一侧,metaclass
名称在语言定义中是硬编码的,而在 def __new__
一侧,将使用第一个参数中的任何名称。
In [98]: class M(type):
...: def __new__(metaclass, name, bases, namespace, **kwargs):
...: return super().__new__(metaclass, name, bases, namespace, **kwargs)
...:
In [99]: class A(metaclass=M):
...: pass
不管怎样,正如我所说,我通常对mcls
感到满意。
相反,同样重要的是:metaclass 上的任何其他方法,在普通 class 上将是 self
的任何其他方法都将作为参数接收 class
使用 metaclass 创建 - 因此通常将这些命名为 cls
而不是 self
,因为这样更容易记住 metaclass 的实例是什么代表.
因此,在方法 __init__
、__getattr__
、__call__
的元 class 中以及任何认为有用的方法中,第一个参数是 cls
而不是 self
.
回到你的一个片段:
class Meta(type):
def __prepare__(metaclass, cls, bases):
return dict()
def __new__(metacls, cls, bases, clsdict):
return super().__new__(metacls, cls, bases, clsdict)
正如我评论的那样,您可以调用第一个参数 metacls
,但是 __new__
和 __prepare__
的 第二个 参数应该是 name
不是 cls
。再次:Python 将这些作为有序参数传递,因此如果您将其命名为 cls
,它将 工作 ,但其内容是声明的 class 名称尽管如此,还是一个字符串。一方面,cls
名称通常指定 class 本身,当调用这些方法时它甚至 不存在 - 它只会从点存在在 __new__
metaclass 方法中调用 super().__new__
的地方。
至于第四个参数,你调用 clsdict
,我知道没有强约定 - clsdict
足够清楚,namespace
- 但多年来,我一直简单地使用 dct
,有时也使用 ns
。
最后,如上所述,我不希望 PyCharm 或任何其他样式荧光笔(或“校正器”)比我更了解我对 metaclass 的意图:我会忽略它们。
我认为 meta类 的使用频率比常规 类 低得多,因此像 self
和 cls
这样强大和广泛的约定不合乎逻辑不存在。
Google 搜索结果稍微偏向 mcs
:
__new__(mcs
3490 个结果
__new__(mcls
2230 个结果
__new__(metacls
1940 个结果
__new__(metaclass
919 个结果
就我个人而言,我会倾向于 metacls
,因为它更具描述性,而且对我来说感觉更符合 cls
。
可以在 File | Settings | Editor | Inspections | Python | Methods having troubles with first parameter
中更改首选值,请参阅屏幕截图: