python中的生锈方法定义
#python #oop #rust

当我浏览生锈文档时,这一切都始于,并注意到在锈语中,与结构本身分开定义。要理解我的意思,请参见从Rust文档中提取的示例。

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

多么不错的功能!我告诉自己。然后我开始在Python中考虑这个。

我们可以在Python中做同样的事情吗?

简短的答案是肯定的,尽管我们需要编写一些代码以使这种样式在Python中成为可能。这是一个简单的解决方案,借助装饰师和猴子斑点。

def impl(cls):
    def wrapper(fn):
        setattr(cls, fn.__name__, fn)
        return fn
    return wrapper

这是一个简单的用法。 dataclass在这里用来类似于rust struct,因为python中没有struct

from dataclasses import dataclass

@dataclass
class Rectangle:
    width: int
    height: int

@impl(Rectangle)
def area(self: Rectangle) -> int:
    return self.height * self.width

if __name__ == "__main__":
  rect = Rectangle(width=10, height=20)
  print(rect.area())

area方法的定义现在不在类定义。


用例

我认为这种样式提供了一些可以在我们未来的Python项目中使用的用例。

分开的实现模块

在某些情况下,实施方法还需要其他一些可能很大且进口缓慢的依赖项。使用此样式,您可以具有类定义和多个实现文件。开发人员仅导入他们想要使用的内容。

功能切换

使用此样式,我们可以具有功能切换,可以在不同的实现之间进行选择。看看以下示例。

def impl(cls: T, condition: bool=True):
    def wrapper(fn):
        if condition:
            setattr(cls, fn.__name__, fn)
        return fn
    return wrapper

请注意,定义方法时执行上述条件,而不是在调用该方法时执行。

from dataclasses import dataclass
from enum import IntFlag, auto

@dataclass
class Rectangle:
    width: int
    height: int

class FeatureFlag(IntFlag):
    FAST_AREA = auto()

@impl(FeatureFlag)
def read_from_config():
    return FeatureFlag.FAST_AREA

实现文件对area方法有两个定义,并且这两个方法通过功能标志控制。

FLAGS = FeatureFlag.read_from_config()

@impl(Rectangle, FeatureFlag.FAST_AREA in FLAGS)
def area(self: Rectangle) -> int:
    return self.height * self.width

@impl(Rectangle, FeatureFlag.FAST_AREA not in FLAGS)
def area(self: Rectangle) -> int:
    area_value = 0
    for _ in range(self.width):
        area_value += self.height
    return area_value

if __name__ == "__main__":
  rect1 = Rectangle(width=10, height=20)
  print(rect1.area())

问题

在python中进行这种黑客攻击,例如mypy


我想使用编程语言,使编程更有趣。
如果您可以在评论中分享您的想法/想法,这将不胜感激。