Есть ли scala-эквивалент python __getattr__ / __setattr__
(и других __*__
методов?). Что-то встроенное или, может быть, какие-то черты?
Scala эквивалент python __getattr__ / __setattr__
Ответы (2)
Что касается __getattr__
и __setattr__
, вам придется подождать, пока кто-нибудь с большей проницательностью не опишет новый API отражения Scala 2.10. (И, конечно же: он никогда не будет напрямую переводиться. Это полностью зависит от вашего варианта использования. Если вам просто нужен динамический класс, в будущем будет черта Dynamic
; если вы просто хотите немного этого, тогда разработка на основе сопоставления с образцом может быть очевидным выбором.)
Что касается множества других __*__
методов в Python:
Глобальные вещи
__call__
→apply()
// поведение практически идентично__metaclass__
// use case dependent:- currently
class
inheritance ortrait
mixins may be useful - во многих случаях все, что делает этот метакласс, - это создание экземпляра, которое избегает вызова
super()
; в Scalasuper()
всегда вызывается в конструкторе.
- currently
__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
Примечательно, что apply
и update
являются особыми в Scala, как и их аналоги в Python. Они допускают следующий синтаксис:
val x = collection(elem) // val x = collection.apply(elem)
collection(elem) = y // collection.update(elem, y)
Точно так же, как __iter__
Python допускает синтаксис типа (el 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__
явно отсутствуют?)
- person Debilski; 19.05.2012
Я не уверен, в чем здесь смысл. Единый принцип доступа Scala означает, что «поля» и методы используют один и тот же интерфейс, потому что, по сути, «поля» в Scala являются геттерами и сеттерами.
Другими словами, вы можете заменить их так:
var x: Int = 0
private[this] var _x = 0
def x = _x
def x_=(n: Int) { _x = n }
Методы получения и установки будут контролировать доступ к объявленному вами частному полю.
Теперь, если все, что вам нужно, это способ предоставить нестатические поля, вам нужно взглянуть на черту Dynamic. Это экспериментальная версия до 2.9.2, но она будет доступна в 2.10, хотя и за флажком, предупреждающим людей, что эта функция опасна (потому что она вводит динамическую типизацию, но если вы не думаете, что динамическая типизация опасна, вам следует отлично).
__getattr__
и __setattr__
не имеют прямого отношения к единому принципу доступа в Python (по крайней мере, с тех пор, как был установлен декоратор property
).
- person Debilski; 19.05.2012
__*attr__()
используются для управления поведением при доступе к атрибутам объекта. - person Ignacio Vazquez-Abrams   schedule 19.05.2012