2016-04-15 9 views
12

Sono uno studente molto dilettante di Python e recentemente ho iniziato a imparare il concetto di classi. Riesco a capire il concetto di classi (molto) in modo approssimativo, ma non riesco a capire perché non possa semplicemente scrivere alcune funzioni invece di scrivere una classe?Perché dovrei usare le classi in python?

Per esempio, (sto imparando da Interactive python) uno dei esercizio dato (che dovrei scrivere utilizzando una classe) è:

  1. aggiungere un metodo distanceFromPoint che funziona in modo simile a distanceFromOrigin eccezione del fatto che prende un Point come parametro e calcola la distanza tra quel punto e il sé.

  2. Aggiungere un metodo reflect_x a Point che restituisce un nuovo Point, uno che è il riflesso del punto sull'asse x. Ad esempio, Point(3, 5).reflect_x() è (3, -5).

Hanno scritto il codice utilizzando le classi in questo modo:

import math 

class Point: 
    """ Point class for representing and manipulating x,y coordinates. """ 

def __init__(self, initX, initY): 
    """ Create a new point at the given coordinates. """ 
    self.x = initX 
    self.y = initY 

def getX(self): 
    return self.x 

def getY(self): 
    return self.y 

def distanceFromOrigin(self): 
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5 

def distanceFromPoint(self, otherP): 
    dx = (otherP.getX() - self.x) 
    dy = (otherP.getY() - self.y) 
    return math.sqrt(dy**2 + dx**2) 

p = Point(3, 3) 
q = Point(6, 7) 

print(p.distanceFromPoint(q)) 

Perché dovrei usare classe quando li posso scrivere semplicemente in questo modo:

def distanceFromPoint(p,q): # they are tuples 
    y = (p[0]-q[0])**(2)+(p[1]-q[1])**(2) 
    return y**(1/2) 

def reflectx(p): 
    return (p[0],-p[1]) 

p = (3,3) 
q = (6,7) 
+1

Almeno i metodi 'getX' e' getY' non sono considerati _pythonic code_. È possibile accedere direttamente agli attributi 'x' e' y'. – Matthias

+1

Oltre alle risposte più generali qui sotto: non hai davvero bisogno del getX/getY. Python non ha membri privati ​​reali, quindi usare solo x/y è ok. Se hai bisogno di sovrascriverli, le proprietà sono sempre disponibili. – viraptor

+0

@Matthias: Sono nuovo di Python. Non riesco a capire cos'è il codice pythonic e perché getX, getY non sono codici pitonici? –

risposta

3

È possibile dichiarare una funzione di fuori di una classe. Ma memorizzarli in classe è una pratica migliore in generale nella programmazione. OOP è considerato più leggibile e riutilizzabile.

E in questo caso, la distanza tra due punti dipende punti, quindi è logico avere il metodo distanceFromPoint in questa classe.

La classe consente inoltre di calcolare la distanza da punti e non di tuple che possono contenere valori non validi, ad esempio più di due coordinate.

+0

Posso definire un controllo (con la funzione if) all'interno della mia funzione di distanza che se i primi due dati (nella tupla) sono interi, quindi calcolare, altrimenti mostrare un errore. Allora perché dovrei usare la classe allora? –

-2

Functional e object-oriented programmazione sono diversi paradigmi.

In Python, tutto è un oggetto, anche int s. L'intero linguaggio va verso la programmazione orientata agli oggetti, ed è per questo che dovresti preferirlo, soprattutto se il tuo programma crescerà.

+4

Stai confondendo ** Programmazione funzionale ** e ** Programmazione imperativa **. La programmazione funzionale non implica l'utilizzo di funzioni. È possibile eseguire ** la programmazione funzionale ** in Python, ma il modo in cui ha descritto il post era ** programmazione imperativa ** – Shiho

8

Uno dei grandi vantaggi dell'utilizzo di OOP è l'estensibilità .

Supponiamo che tu abbia scritto un'applicazione che elabora molti dati sotto forma di punti. Ora il tuo cliente aggiunge alle specifiche che oltre alle coordinate xey di ogni punto, la tua app deve sapere di che colore è ciascun punto.

Se è stato scritto il codice per memorizzare ciascun punto come una tupla, (x, y), è possibile aggiungere il colore come un terzo valore: (x, y, colour). Ma ora devi passare attraverso tutto il tuo codice per trovare i punti in cui è rotto perché hai cambiato il formato dei dati.Se avevo usato una classe, si può semplicemente definire una nuova classe che eredita da Point e aggiunge le capacità necessarie:

class ColouredPoint(Point): 
    """ Class for points which are coloured, based on Point """ 

    def __init__(self, initX, initY, initCol): 
     Point.__init__(self, initX, initY) 
     self.colour = initCol 

p = ColouredPoint(3, 3, "green") 
q = ColouredPoint(6, 7, "red") 
r = Point(8, 4) 

print(p.distanceFromPoint(q)) 
print(p.colour) 
print(p.distanceFromPoint(r)) 

Tutto il codice che ha lavorato con la classe Point continuerà a funzionare con la nuova classe, e puoi farlo anche se non hai scritto, o non puoi cambiare, la definizione della classe Point.

+0

Cosa intendi per codice non funzionante? Una funzione senza classe non può trascurare i valori aggiuntivi? Ad esempio, mentre si scrive codice senza classe, potrei avere una stringa su p [2] come una tupla, e la tupla trascurerà quella calcolando la distanza. –

+0

Questo è vero, ma per quanto riguarda la funzione 'reflectx' nella domanda - perderebbe i dati aggiuntivi.Sono sicuro che tu possa trovare una soluzione, ma spero che tu veda che più modifiche ed estensioni sono possibili all'originale a cui pensi, più diventa difficile ideare un tipo di dati che si comporti sempre correttamente. Quando si arriva alla complessità delle applicazioni del mondo reale, OOP è molto più semplice e robusto, e quanto sopra è solo uno dei motivi per utilizzare OOP. – nekomatic

+0

Mi manca qualcosa se riassumo la necessità della classe come "Aggiungere nuove funzioni (per manipolare alcuni oggetti) o modificare la struttura dell'oggetto, in modo efficiente"? Quali sono gli altri motivi per utilizzare OOP? –

1

L'esempio di un punto è negativo per giustificare l'uso delle classi.

Una classe è un ottimo modo di descrivere che cosa è piuttosto che manipolare i dati. Quindi un punto ha solo due bit di informazioni che lo descrivono (nello spazio 2D comunque).

Pensa a qualcosa di più astratto, come un file di film. I film hanno tutti i tipi di informazioni associate: titolo, durata, generi, attori, età, popolarità, lingua, premi ... continua. Prova a scrivere le funzioni che gestiscono un lungo elenco di tutte queste informazioni e vedrai rapidamente i pregi di una classe.

La matematica è forse l'area in cui non ci sono molte informazioni contestuali, ci sono solo poche variabili e definiscono tutto. I dati del mondo reale sono definiti in modo meno chiaro e quindi beneficiano dell'estensibilità delle classi.

+0

Puoi per favore elaborare il tuo secondo para (Una classe è un grande ...)? Non riesco a capirlo chiaramente senza molti esempi e sono nuovo in Python. –