Domanda sulla OOP

sia in Python che in C# ci sono le classi per la quale è possibile la programmazione OOP
considerando che comunque sia, è anche possibile usare metodi statici in entrambi i casi
che quindi danno la possibilità per l’appunto di non creare istanze di più oggetti della stessa
nella programmazione in Rhino, che senso ha dover scrivere codici utilizzando le istanze?

es. utilizzando rhinoscriptsyntax sia con VBS e Py in quel caso non utilizzavo le istanze, in una
programmazione diciamo più articolata, sono necessarie le istanze, oppure se ne può fare
a meno, o ancora se ne può fare a meno, ma in certi casi, si è obbligati ad usarle?

Ciao Salvio

Secondo me i metodi non sono cosi’ importanti quando decidi se utilizzare delle istanze.
EDIT:
Credo di capire cosa intendi: utilizzare metodi statici per poter scrivere in modo procedurale, anziche’ in modo OOP. Giusto.
/EDIT
Le istanze sono dei dati compositi, come puo’ esserlo una lista, una stringa, un dizionario …
Se parliamo di classi scritte da te, io sceglierei il modo piu’ comodo per scrivere il tuo script.
Se e’ piu’ comodo utilizzare una classe con le sue istanze, scrivi una classe.
Se no lascia stare le classi, o comunque non usare delle istanze.
Dipende molto dai gusti personali.

Discorso diverso se usi una libreria.
Se la libreria e’ composta da classi, bisogna usare quelle.

In VBS per definire un punto usi una Array, che in rhinoscriptsyntax diventa una lista. OK.
Se usi RhinoCommon invece di solito usi istanze della struct Point3d.
Ma nessuno ti vieta, in Python o in C# di usare le liste per definire i punti, certo in questo modo rinunci a usare RhinoCommon.
… Potresti anche usare 3 variabili per ogni punto … o altro ancora.
E’ una scelta.

In fondo le classi, parlando di dati, sono solo un nome (relativamente) nuovo per cose che si sono sempre usate.
I dati compositi sono sempre esistiti, ma potevano essere chiamati struct oppure record ecc.,
o anche semplicemente liste o array.

… Mi sa che ti sei imbattuto in un problema fondamentale (se non nel problema fondamentale) riguardo alla programmazione.
La scelta della struttura dati.
:grinning:

1 Mi Piace

e si Emilio, in questa fase credo che dipenda il buon esito del codice
(intendo anche la possibilità di completare o meno il codice)

se parto a scrivere un codice in un modo, ma poi ad un tratto noto che la struttura impostata inizialmente non va bene, a quel punto credo che l’unica strada possibile da scegliere è ricominciare da capo. . .
e onestamente vorrei evitarlo.

esatto intendevo proprio questo, nel caso poter anche usare le classi ma senza le istanze

in che senso rinuncio a RCommon?
se scrivo un codice che contiene una semplice def, dove eseguo il metodo: RhinoGet.GetOneObject
sto già utilizzando RCommon?

Mah … a me sembra normale tentare una strada e poi accorgersi che non funziona e cambiare idea.
Penso lo facciano anche i professionisti.
Figurati noi dilettanti … :smile:

Nel senso che non usi i vari Point3d, Line, Curve, Surface ecc. e tutti i loro metodi e proprieta’.
Ma a questo punto secondo me stai tornando a usare principalmente rhinoscriptsyntax, e anche questa puo’ essere una scelta.

Il nome completo di quel metodo e’: Rhino.RhinoInput.RhinoGet.GetOneObject.
Inizia con Rhino. quindi appartiene a RhinoCommon.
E in ogni caso, quel metodo restituisce una instanza ObjRef, da cui a sua volta puoi ricavare delle istanze ad esempio Curve o Brep o altro.
Se non vuoi usare le istanze, cosa te ne fai di RhinoGet.GetOneObject ?
:wink:

Ma stiamo parlando di classi RhinoCommon.
Non ho capito se tu volevi evitare di usare istanze di classi scritte da te …
O se pensavi di evitare anche quelle di classi e strutture di RhinoCommon. :confused: :slight_smile:

quello che ho in mente, e di non usare rhinoscriptsyntax per convertire i miei script
(essendo che in pratica ho tutti i miei script in VBS quindi sarebbe una copia in Py)
ma usare esclusivamente i metodi Namespaces

le istanze che intendevo capire in quali casi usarli e in quali no, sono tipo questo es.:

class Classe1:
    lista = []
    def Def1(self):
        self.lista.append(1)
        print self.lista[0]
Classe1().Def1() # output: 1

class Classe2:
    lista = []
    @staticmethod
    def Def1():
        Classe2.lista.append(2)
        print Classe2.lista[0]
Classe2().Def1() # output: 2

giusto per dare un’idea, in entrambi i casi le classi riportano un print con un valore
se ho assimilato bene i concetti OOP, la prima classe usa una istanza, la seconda invece no

come dicevo in Py come anche in C# usando i metodi statici si possono chiamare metodi senza fare
uso delle istanze, e quindi come anche avevi detto prima, usare un modo procedurale per l’appunto.

in conclusione, e riassumendo il concetto: sempre usando solo RCommon, se mi serve selezionare due o più curve per trovare le intersezioni tra di loro mi serve utilizzare le istanze? come anche avere un n di punti e selezionarli per poi per dire creare dei cerchi o cose simili, mi serve utilizzare le istanze? oppure come credo ne posso fare a meno? (tenendo conto che in certi casi bisogna ricorrere alle classi)

ovviamente se sono nate le classi per gli OOP con l’uso delle istanze ci sarà un motivo, poter fare cose che prima non si potevano fare, oppure non so rendere anche più facile un determinato tipo di codice.

ps Emilio, ho visualizzato alcuni dei tuoi script che hai condiviso qui sul forum,
da quello che ho visto, in genere quando utilizzi le classi fai uso delle istanze.

in pratica nel scrivere uno script per usarlo in Rhino, mi sfugge il senso delle istanze. . .
tanto per esprimere il concetto del mio ragionamento, basandomi quando in C# si è usata la classe
“Persona o Studenti” per creare le istanze di quella classe. (e fin qui ho compreso il ragionamento)
ma quello che mi chiedo è: se debbo scrivere un codice per delle intersezioni oppure unire dei punti
con una curva, creare nuovi oggetti ecc in questi casi a che serve usare le istanze di una classe?

esecuzione: clicco un pulsante e mi crea un cerchio, lo ri-clicco e me ne crea un’altro e così via,
non mi serve utilizzare le istanze per avere un cerchio ogni volta che clicco sul pulsante giusto?

Quindi parli di classi definite da te nello script.
Non parli di classi e struct di RhinoCommon.
Giusto ?

Cioe’ vuoi sapere se nei tuoi script dovrai spesso scrivere cose come:

Mentre non hai problemi ad utilizzare le classi di RhinoCommon.

In pratica vorresti limitarti ad utilizzare le classi gia’ definite in RhinoCommon,
senza bisogno di definirne di nuove.

Ho capito bene ?

Scusa, ma se non capisco prima bene di quali istanze parli, non so cosa dire … :grinning:

NO!

Esistono certe proprietà o metodi che sono indipendenti dalla classe e risulta conveniente
definirli statici. L’esempio che hai fatto in python se lo replichi con un linguaggio più “rigoroso” ti
restituisce un errore. Ecco un altro motivo (personale) per stare alla larga dalla serpe!
In entrambe le classi il metodo Def1 modifica la proprietà lista aggiungendo un elemento e
lo stampa a video. In realtà “dietro le quinte” l’interprete crea una istanza della classe
ed esegue il metodo Def1 (oppure fa qualcosa di ancor più intelligente …).
Un metodo è statico solo se è indipendente dalle proprietà della classe. Ad esempio:

    def StampaDue():
        print 2

Solitamente i metodi statici vengono usati per restituire costanti oppure per eseguire
operazioni generiche indipendenti (conversioni, trasformazioni ecc…).

Per definire due studenti distinti devi per forza definire due istanze:

istanze distinte = dati distinti

Be’, Python consente di invocare un metodo statico anche tramite un’istanza.
Se non sbaglio e’ quanto fa anche il C++. ( Non ho idea C# :smile:)

O parli di altro ? :slight_smile:

No, non puoi farlo. Quando scrivi Classe2.lista.append(2) sicuramente
restituisce errore perché lista è dichiarata ma non inizializzata, Se lista
fosse dichiarata static allora viene alloccata in memoria all’avvio dell’eseguibile
e accessibile da tutti (diventa una variabile globale …).

E’ questo che intendevo.
( Veramene intendevo che c’e’ scritto Classe2().Def1() e non Classe2.Def1(), quindi c’e’ di mezzo una istanza … ma torniamo all’errore. :smile: )
Per Python quella lista e’ una variabile static, per cosi’ dire.
E’ relativa alla classe, non alle istanze. Ce n’e’ una sola.
E qui e’ inizializzata con la lista vuota. lista = []

… Comunque speriamo di capire di quali istanze sta parlando Salvio …
Perche’ altrimenti sono di nuovo bloccato.
Per me ogni valore e’ una istanza di qualche tipo (nel senso di data type),
poi come sempre possiamo dare interpretazioni diverse ai vari nomi.
:confused:

1 Mi Piace

Ottimo. Non avevo fatto caso :upside_down_face:

1 Mi Piace

ciao Sergio, ma parli del mio esempio che ho postato?
perché funziona non da errori Classe2().Def1() # output: 2
infatti ho riportato output che riscontro avviando il codice, o intendevi altro?

(ho una brutta abitudine, che quando posto un codice, quasi sempre li provo prima)

Leggi il mio post precedente.
Che funzioni non ho dubbio …

1 Mi Piace

cerco di formulare la domanda in un’altra maniera:

ribadendo il concetto posto inizialmente, che scopo hanno le istanze nell’eseguire i metodi?
(con i “metodi” intendo le API di RhinoCommon: Namespaces)

ok nel caso degli Studenti la situazione mi è ben chiara in questo caso non ci sono problemi
per ogni Studente da generare si crea una nuova istanza e fin qui ok

ma se scrivo un codice che deve eseguire una sequenza di operazioni consecutive;
(parlo sempre di operazioni basate su RCommon quindi metodi ecc ecc)
le operazioni da eseguire saranno sempre singole operazioni e mai multiple
in pratica sarà sempre è solo un’unica istanza per ogni metodo.

ps per lo meno al momento, questo riesco a capire poi di sicuro sbaglio, ma
con le info che ho a disposizione attualmente più di questo non riesco a fare

(spero di aver chiarito un po meglio la domanda perché altrimenti non so come fare in altro modo. . .)

Le istanze sono i dati con cui lavora il tuo script: dei punti, delle curve, dei layer ecc. ecc. ecc.
I metodi eseguono operazioni sui dati. A volte li modificano, a volte ne creano di nuovi.
Le istanze non servono per eseguire i metodi.
I metodi servono per lavorare con le istanze, cioe’ con i dati.
EDIT:
Sintetizzando.
I metodi sono il mezzo. Le istanze sono il fine.
Non viceversa.
/ EDIT

Tra parentesi …
Anche quando usi rhinoscriptsyntax stai usando delle istanze (non di RhinoCommon)
I Guid sono tutti istanze di questa struct:

Quando nel tuo script hai bisogno di dati piu’ complessi di un numero, una stringa o una lista, ad esempio oggetti geometrici, userai delle istanze di qualche classe o struct definita da RhinoCommon.
Sono fatte apposta per poter lavorare agevolmente con dati complessi (come una curva, ad esempio).

Attenzione, scusa se ripeto, ma mi sembra che sia questo il dubbio.
L’istanza non la creiamo per poter utilizzare il metodo.
La creiamo per costruire, per definire i nostri dati nello script.
Le istanze costituiscono i dati nel nostro script.
E’ il metodo che e’ al servizio dell’istanza, non viceversa.
Usare un metodo e’ come usare una normale funzione Python: serve ad elaborare i dati, cioe’ le istanze.
Se RhinoCommon comprendesse solo metodi statici non cambierebbe niente, a parte un pochino la sintassi. Ma sarebbe la stessa cosa, lavorerebbe allo stesso modo.

Infine, se non usi le istanze, come fai a interagire con Rhino ?
Se selezioni una superficie, otterrai una istanza di Surface.
Se devi disegnare un cerchio, devi passare al metodo apposito una istanza di Circle.

Non saprei come impostare uno script per Rhino senza usare delle istanze.
Tu come faresti ? Che dati utilizzeresti ?

Poi, se posso essere indiscreto, non capisco per quale motivo non vorresti utilizzare le istanze di RhinoCommon.

1 Mi Piace

Senza un esempio reale è come parlare di sesso degli angeli.

Non saprei cosa aggiungere …

non’é che non voglia usare le istanze, e che vorrei usarle consapevolmente,
se in determinati casi non sono necessarie riconoscere la situazione e optare per altra strada.

il termine istanza l’ho iniziato a sentire (o meglio leggere) quando nel forum si è parlato
degli OOP tramite Python la identificavo con la parola “self” in C# con la parola “new”

adesso invece anche usando rhinoscriptsyntax senza RCommon si parla che si fa uso di istanze
ovviamente se anche in questa circostanza vengono create istanze è ovvio che il mio pensiero non vale.

infatti a limite poteva essere una prova da fare, ma da ciò che dici credo non sia nemmeno possibile.

e che dire. . . grazie come sempre per le spiegazioni
(anche stavolta avevo preso un’abbaglio quindi)

Penso che tu abbia incontrato questo nuovo ‘parolone’ :wink: che ti ha confuso. :slight_smile:
Istanza, in OOP e’ sinomino di Oggetto … da cui appunto la OOP, che usando la parola “istanza” suonerebbe come IOP … :smile:
Ma e’ sempre la stessa cosa.
In OOP, un oggetto o una istanza sono semplicemente un valore, un dato.
Non c’e’ ragione per cercare di evitare le istanze.
Significa voler evitare i dati … E visto che l’informatica si occupa di elaborazione dati, la cosa suonerebbe un po’ strana … :confused: :smile:
Quando programmi non cerchi di evitare i numeri o le stringhe o le liste.
Non avrebbe senso. Allo stesso modo non ha senso evitare le istanze.
Quando tu scrivi 5 stai usando una istanza di int.
Quanto scrivi “Saluti a tutti !” stai usando una istanza di str.
Se scrivi [ 11, 22, 33 ] usi una istanza di list.
… E quando ti serve una curva, userai una istanza di Curve.
Allo stesso modo non ha senso evitare i metodi.
Quando scrivi

a = [ 11, 22 ]
a.append( 33 )

stai usando un metodo di list.
Quando scrivi

c = 'pippo pluto paperino'
d = c.split()

stai usando un metodo di str.
Istanze e metodi sono i nomi che la OOP usa per dati e funzioni/procedure.
E’ solo questione di nomi.
Certo la sintassi cambia un poco, ma non ci spaventiamo mica per una sintassi un po’ diversa, no ? :wink:
A maggior ragione se vuoi utilizzare C#.
C# e’ totalmente orientato agli oggetti. Senza le classi non si puo’ usare.
E’ fatto cosi’ ( … poveretto :smile:).
Python e’ un po’ diverso. Fino a un certo punto si puo’ usare in modo procedurale, ma come abbiamo visto, basta utilizzare una lista o una stringa che … Zac! Facilmente ripiombiamo nella OOP.
Pazienza. :wink:
I linguaggi sono quello che sono, e di solito funzionano bene, quindi impariamo a usarli senza farci tanti problemi. :grinning:

Come abbiamo visto, una istanza e’ semplicemente un dato.
self si usa nei metodi Python e corrisponde a this in C#.
Entrambi indicano quel parametro particolare che hanno i metodi OOP, quello che quando richiami un metodo scrivi prima del punto.
new serve a costruire nuovi oggetti (istanze) in C# mentre in Python non c’e’ una parola per questo, basta il nome della classe.

1 Mi Piace

daccordo su tutto, unica cosa che mi rimane il dubbio che forse non era chiaro, e che io non voglio
“evitare di usare le istanza”, sopratutto adesso che come mi hai spiegato è impossibile essendo
che anche una lista a quanto pare è un’istanza, quindi sarebbe meglio dire “evitare di creare istanze”

nel senso di creare istanze con il codice da me scritto

tipo come nei due modi che hai specificato appunto.

OK.
Ci sono dei motivi per cui preferisci non creare istanze ?