Единственный способ, которым я знаю это сделать в стандартной библиотеке Python, - использовать свойство, так что соответствующее значение вычисляется каждый раз, когда к нему обращаются:
class Thing(object):
def __init__(self, x, y_add):
self.x = x
self.y_add = y_add
@property
def y(self):
return self.x + self.y_add
In use:
>>> t = Thing(2, 10)
>>> t.x
2
>>> t.y
12
>>> t.x = 3
>>> t.y
13
В противном случае вам нужно будет вызвать функцию (y()
вместо y
) или использовать что-то вроде sympy
.
Идиоматический Clojure поддерживает определение независимых функций, которые работают с очень небольшим набором основных структур данных; такое разделение методов и данных является сильным заявлением против объектной ориентации и в пользу функционального стиля. Рич Хики (создатель Clojure) неоднократно заявлял о важности этого; например, здесь: «Clojure избегает традиционного объектно-ориентированного подхода к созданию нового типа данных для каждой новой ситуации, вместо этого предпочитая создавать большую библиотеку функций на небольшом наборе типов». .
Опора на основные структуры данных в Clojure даже более важна, чем в других функциональных языках, потому что вы сможете в полной мере воспользоваться преимуществами Clojure STM только тогда, когда будете использовать постоянные структуры данных Clojure.
Я предполагаю следствие этого вопроса - когда полиморфизм можно считать отличным от ориентации объекта?
Полиморфизм не имеет абсолютно никакого отношения к объектной ориентации. Это просто означает, что одна и та же операция может вести себя по-разному в зависимости от типа (типов) ее операндов.
Функциональные языки, такие как ML или Haskell, имеют полиморфизм более 30 лет, и кто-то, кто лучше знает историю PL, может указать на некоторые примеры до 1962 года (то есть до OO).
Кристофер Стрейчи описал различие между параметрическим полиморфизмом и специальным полиморфизмом в 1967 году, поэтому полиморфизм, должно быть, уже существовал тогда. Поскольку полиморфизм был введен только в ОО в Simula-67, я предполагаю, что полиморфизм должен существовать до того, как он был введен в ОО.
Clojures Полиморфизм является естественным расширением Java. В Java методы отправляются в соответствии с классом. В ближайшем будущем это расширяется, чтобы позволить вам отправлять вызовы на основе всего, что вы хотите. Его по-прежнему очень легко отправить на урок, и в большинстве случаев так оно и есть. Если вы хотите что-то еще, вы можете написать своего собственного диспетчера. Встроенная функция derive
для создания иерархии, основанной на чем угодно, и последующей отправки по isa
.
больше добра в: http://clojure.org/multimethods
Вы должны использовать Grandpa :: __ construct ()
, другого ярлыка для него нет. Кроме того, это нарушает инкапсуляцию класса Papa
- при чтении или работе с Papa
можно с уверенностью предположить, что метод __ construct ()
будет вызывается во время строительства, но класс Kiddo
этого не делает.
Объединение методов со структурами данных - это то, что Clojure не рекомендует.
Сказав все это. ... на самом деле у функций есть ограничения на то, с какими аргументами они будут работать. first rest и nth будут работать только с тем, что может быть seq. С этой точки зрения нет большой разницы, связаны ли структуры данных с методами или нет - вам все равно нужно правильно сопоставить их. Большая выгода от гибкости. Функции могут быть написаны так, чтобы принимать любые аргументы, а затем составляться из функций более высокого порядка без определения классов и т. Д.:
(def farms [{:name "Swansea", :value 100}
{:name "Broadmarsh", :value 200, :produce [:corn :wheat :rye]}
{:name "Snug", :value 50, :animals [:goats :pigs]}])
(reduce + (map :value farms))
-> 350
(reduce + (map :value (filter :animals farms)))
-> 50