Se pregunta sobre el rendimiento es innecesaria cuando es tan fácil de medir:
$ python -mtimeit -s'class X(object):
> @property
> def y(self): return 23
> x=X()' 'x.y'
1000000 loops, best of 3: 0.685 usec per loop
$ python -mtimeit -s'class X(object):
def y(self): return 23
x=X()' 'x.y()'
1000000 loops, best of 3: 0.447 usec per loop
$
(en mi portátil lenta - Si usted se pregunta por qué el segundo caso no tiene indicaciones de concha secundarias, es porque he construido desde el primero con una flecha hacia arriba en bash, y eso repite la estructura de salto de línea, pero no las indicaciones! -).
De modo que, a menos que esté en un caso en el que sepa que más de 200 nanosegundos importará (un bucle interno cerrado que está tratando de optimizar al máximo), puede permitirse usar el enfoque de propiedad; Si realiza algunos cálculos para obtener el valor, los 200+ nanosegundos se convertirán, por supuesto, en una fracción más pequeña del tiempo total empleado.
Estoy de acuerdo con otras respuestas en que si los cálculos son demasiado pesados, o puede que quiera parámetros, etc., es preferible un método; de manera similar, agregaré, si alguna vez necesita esconder el llamamiento en algún lugar pero solo llámalo más tarde, y otros trucos de programación funcional extravagantes; pero quería hacer el punto de rendimiento cuantitativamente, ya que timeit
hace tales mediciones tan fáciles! -)
Y los resultados son aún más cercanos (en porcentaje) si no cuenta la creación de instancia 'x', (utilicé la función mágica'% timeit' en iPython): 'x = X();% timeit x.y' -> 1000000 loops, lo mejor de 3: 211 ns por ciclo; 'x = X(); % timeit x.y() '-> 10000000 loops, lo mejor de 3: 169 ns por ciclo –