scala中对应python的__getattr__ / __setattr__。

12 浏览
0 Comments

scala中对应python的__getattr__ / __setattr__。

在Scala中是否有与Python的__getattr__ / __setattr__(以及其他__*__方法)等效的方法?是否有内置的方法或者一些特质可以实现类似功能?

0
0 Comments

Scala中的等效方法是使用getter和setter方法来控制对私有字段的访问。如果想提供非静态字段,可以使用Dynamic trait。该trait在Scala 2.9.2中是实验性的,但在2.10中已经可以使用,不过需要通过一个标志来警告用户该特性是危险的(因为它引入了动态类型,但如果你认为动态类型不是危险的,那就没问题)。

在Python中,__getattr____setattr__与统一访问原则没有直接关系(至少在property装饰器被引入之后就没有了)。

0
0 Comments

在Scala中,没有直接等价于Python中的`__getattr__`和`__setattr__`的方法。这取决于你的用例,如果你只是想要一个动态类,Scala中将会有一个`Dynamic`特质;如果你只是想要其中一小部分功能,那么围绕模式匹配进行设计可能是一个明显的选择。

至于Python中的其他`__*__`方法,以下是它们在Scala中的等价方法:

全局方法:

- `__call__` → `apply()`,行为几乎相同

- `__metaclass__`,在Scala中使用取决于具体的用例:

- 目前,类继承或trait混入可能非常有用

- 在许多情况下,元类所做的全部工作就是实例构造,避免了对`super()`的调用;在Scala中,构造函数总是调用`super()`

- `__repr__`、`__str__` → `toString()`

- `__eq__` → `equals()`

- `__init__`,在类体中隐式调用

- `__new__`,直接不存在;根据用例的不同,可以使用早期初始化

- `__del__`,缺失

- `__nonzero__`,除了`implicit def toBool[MyType](a: MyType): Boolean = ...`之外并没有等价方法

容器类型:

- `__len__` → `length`、`size`或容器约定中的其他命名

- `__getitem__` → `apply(i: IndexType)`,在Scala中容器是函数

- `__setitem__` → `update(i: IndexType, v: ValueType)`

- `__delitem__`,不需要特殊处理,根据容器约定即可

- `__iter__` → `foreach(block: ValueType => Unit)`,带返回值的情况下可以使用`map`、`flatMap`

值得注意的是,在Scala中,`apply`和`update`与其Python对应方法一样是特殊的。它们允许以下语法:

val x = collection(elem) // val x = collection.apply(elem)
collection(elem) = y // collection.update(elem, y)

类似地,就像Python的`__iter__`允许`for (el in container)`这样的语法一样,`foreach`和`map`使得`for (el <- container) yield el`成为可能。

运算符:

一般情况下,我们可以直接定义这些方法:

- `__add__`、`__sub__`等,只需定义`def + (arg: T)`或`def - (arg: T)`

- 包括比较运算符在内,例如`__lt__`、`__ge__`,可以定义`def <(other: T)`、`def <=(other: T)`

然而,就像Python一样,编译器对于一些高级事项有一些特殊情况:

- `__radd__`、`__rsub__`等,右结合的运算符,近似于`def +: (arg: T)`或`def -: (arg: T)`(在方法名后添加一个冒号)

- `__iadd__`、`__isub__`等,修改操作符:`def += (arg: T)`等

上下文管理器:

- `__enter__`、`__exit__`,在大多数情况下,可以使用函数参数来实现相同的目的

另外,可以参考Scala的“魔术”函数列表。但是除了`__getattr__`和`__setattr__`方法显然缺失之外,是否还有其他问题?

0