Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Roborock Qrevo Curv 2 Flow: ora lava con un rullo
Roborock Qrevo Curv 2 Flow: ora lava con un rullo
Qrevo Curv 2 Flow è l'ultima novità di casa Roborock per la pulizia di casa: un robot completo, forte di un sistema di lavaggio dei pavimenti basato su rullo che si estende a seguire il profilo delle pareti abbinato ad un potente motore di aspirazione con doppia spazzola laterale
Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite
Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite
Abbiamo guidato per diversi giorni la Alpine A290, la prima elettrica del nuovo corso della marca. Non è solo una Renault 5 sotto steroidi, ha una sua identità e vuole farsi guidare
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile
Abbiamo provato a fondo il nuovo Magic 8 Lite di HONOR, e per farlo siamo volati fino a Marrakech , dove abbiamo testato la resistenza di questo smartphone in ogni condizione possibile ed immaginabile. Il risultato? Uno smartphone praticamente indistruttibile e con un'autonomia davvero ottima. Ma c'è molto altro da sapere su Magic 8 Lite, ve lo raccontiamo in questa recensione completa.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 18-07-2010, 11:48   #1
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
[Guida] Python e decoratori

Ho scritto questa "guida" sui decoratori in Python dato che molti li considerano ostici e poco chiari e in italiano non c'era praticamente nulla.
Non è di certo il massimo della chiarezza e il mio talento da scrittore evidentemente non esiste o se esiste è molto nascosto Ma spero che possa essere utile a qualcuno.

Buona lettura!

--------------------------------------------------------------------------

I decoratori, spesso, mettono in difficoltà o fanno paura anche ai programmatori più navigati. Sarà il loro nome, sarà che a prima vista sembrano arabo, ma fattostà che è cosi.

Ma cerchiamo di capire un pò meglio cosa sono questi fantomatici "decoratori".

Cosa è e cosa fa un decoratore?

Un decoratore è una normale funzione che modifica un'altra funzione. Quando si usa un decoratore, Python passa la funzione da decorare al decoratore, e la sostituisce con il risultato. Facciamo un esempio senza usare la sintassi tipica dei decoratori:

Codice:
def mio_decoratore(funzione_da_decorare):
    #fai qualcosa con la funzione, per es.
    funzione_da_decorare.prova = "prova"
    return funzione_da_decorare

def molt(a, b):
    return a * b

molt = mio_decoratore(molt)
Cosa abbiamo fatto? Per prima cosa abbiamo definito una funzione "molt"(che rappresenta la nostra funzione da decorare) che effettua la moltiplicazione tra due numeri e successivamente l'abbiamo sostituita con la funzione restituita da "mio_decoratore", che altro non è che la funzione "molt" modificata. Infatti, se proviamo a digitare:

Codice:
molt.prova
otteniamo:

Codice:
'prova'
Adesso scriviamo un altro codice che fa la stessa identica cosa, ma che usa la sintassi tipica dei decoratori:
Codice:
def mio_decoratore(funzione_da_decorare):
    funzione_da_decorare.prova = "prova"
    return funzione_da_decorare

@mio_decoratore
def molt(a, b):
    return a * b
La sintassi è molto semplice: basta mettere sopra la funzione da decorare il simbolo @ seguito dal decoratore, in questo caso "mio_decoratore"(può avere un nome qualunque, ovviamente).

Internamente Python applica la funzione decorata al decoratore e la sostituisce con il valore restituito da quest'ultimo. Proprio come nel primo esempio. Semplice no?

Domanda: ma un decoratore deve restituire per forza una funzione? No. Può restituire tutto quello che volete, ma la sua utitlità diventa praticamente nulla Immaginate un caso come questo:
Codice:
def decoratore_inutile(funzione_da_decorare):
     return True

 @decoratore_inutile
 def molt(a, b):
     return a * b
Adesso "molt" non è più una funzione, ma un valore booleano, cioè True. Se provate a chiamarla, otterrete il fatidico "TypeError":
Codice:
>>>molt(5, 5)
>>>TypeError: 'bool' object is not callable
Come vedete non è che serva a molto

Un decoratore può restituire una funzione arbitraria, ricordate? Questa funzione la chiameremo "wrapper" e sarà subito chiaro il perchè.
Il giochetto sta nel definire la funzione wrapper all'interno del decoratore, in modo che possa utilizzare le variabili presenti nel suo name space, inclusa quindi anche la funzione da decorare che verrà passata al decoratore.

Codice:
def mio_decoratore(funzione_da_decorare):
    def wrapper():
        print "Sono dentro la funzione wrapper e posso accedere " \
               "alla funzione %s" % funzione.__name__
        return funzione_da_decorare()

    return wrapper

@mio_decoratore
def foo():
    print "Io sono la funzione da decorare"

>>>foo()
Sono dentro la funzione wrapper e posso accedere alla funzione foo
Io sono la funzione da decorare
Come vedete la funzione wrapper può fare quello che vuole alla funzione da decorare. Ma qualcuno a questo punto si potrà chiedere: e se devo passare degli argomenti alla funzione da decorare?

Semplice: li passiamo alla funzione wrapper. Questo perchè? Perchè quando usiamo il decoratore, la funzione wrapper sostituirà la funzione da decorare. Quindi sarà lei a ricevere gli argomenti in modo da poterli usare per il proprio scopo.

Dal momento che un decoratore può lavorare con qualunque funzione, non sappiamo quanti argomenti avrà la funzione da decorare, quindi il problema si risolve semplicemente facendo accettare alla funzione wrapper argomenti arbitrari non posizionali e a parola chiave, che poi passerà alla funzione da decorare. Ma facciamo un esempio chiarificatore:
Codice:
def mio_decoratore(funzione_da_decorare):
    def wrapper(*args, **kwargs):
        print "Stiamo chiamando la funzione %s con argomenti " \
                "%s e parole chiave %s" % (funzione_da_decorare.__name__, args, kwargs)
        return funzione_da_decorare(*args, **kwargs)

    return wrapper

@mio_decoratore
def molt(a, b, foo = "foo"):
    print foo
    return a * b

>>>molt(1, 2)
Stiamo chiamando la funzione molt con argomenti (1,2) e parole chiave {}
foo
2
Con gli argomenti possiamo fare ciò che vogliamo, ad esempio:
Codice:
def mio_decoratore(funzione_da_decorare):
    def wrapper(*args, **kwargs):
        kwargs['foo'] = "argomento modificato"
        print "Stiamo chiamando la funzione %s con argomenti " \
       "%s e parole chiave %s" % (funzione_da_decorare.__name__, args, kwargs)
        return funzione_da_decorare(*args, **kwargs)

    return wrapper

@mio_decoratore
def molt(a, b, foo = "foo"):
    print foo
    return a * b

>>>molt(1, 2)
Stiamo chiamando la funzione molt con argomenti (1,2) e parole chiave {'foo': 'argomento modificato'}
argomento modificato
2
Potresti aver bisogno di personalizzare il comportamento del tuo decoratore passandogli delle opzioni.
Per fare questo dobbiamo definire la nostra funzione decoratore dentro un'altra funzione, che chiameremo "opzioni". Nel momento in cui vogliamo decorare una funzione si usa la solita sintassi(@nome_decoratore), ma invece di usare il nostro decoratore useremo la funzione "opzioni". Vediamo subito un esempio:
Codice:
def opzioni(valore):
   def mio_decoratore(funzione_da_decorare):
       funzione_da_decorare.prova = valore
       return funzione_da_decorare
   return mio_decoratore

@opzioni('test')
def molt(a, b):
   return a * b

>>>molt(5, 5)
25
>>>molt.prova
'test'
Non cambia poi molto no? Solo che adesso il nostro decoratore si trova in un ambito dinamico, invece di uno statico

E se insieme alle opzioni vogliamo usare anche una funzione wrapper? Il procedimento è esattamente lo stesso:
Codice:
def opzioni(nome):
    def mio_decoratore(funzione_da_decorare):
        def wrapper(*args, **kwargs):
            kwargs.update({'nome': nome})
            print "Chiamo la funzione %s" % funzione_da_decorare
            return funzione_da_decorare(*args, **kwargs)
        return wrapper
    return mio_decoratore

@opzioni("pinco")
def stampa_nome(nome = None):
        print "Ciao ", nome
Come avrete già capito, la funzione "opzioni" restituisce il decoratore, che Python userà normalmente; cioè, passerà la funzione da decorare al decoratore e verrà restituito il risultato. Infatti:
Codice:
>>>stampa_nome
>>><function wrapper at 0x00BBA930>
vedete che "stampa_nome" non è la funzione decoratore(come invece si potrebbe pensare), ma bensì la funzione wrapper. E' quindi evidente che la nostra funzione da decorare("stampa_nome") è stata passata implicitamente per noi da Python ed è stata sostituita con il valore restituito dal decoratore. Bello no?

Questo è più o meno tutto.

Esempi d'uso, i decoratori @staticmethod, @classmethod e @property

Riferimenti:

modulo "decorator" scritto da Michele Simionato

--------------------------------------------------------------------------

Il contenuto di questo post è rilasciato con licenza Creative Commons Attribution-Noncommercial-Share Alike 2.5

Ultima modifica di Ryuzaki_Eru : 20-07-2010 alle 12:01.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2010, 13:29   #2
das
Senior Member
 
Iscritto dal: Jan 2001
Città: Livorno
Messaggi: 1383
Grazie e complimenti per la tua guida, è la prima volta che sento parlare di decoratori (avrò usato python 3 volte), solo che non mi immagino un caso pratico in cui serva usarli e semplifichino la vita.
Potresti fare un esempio?

Ciao
das è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2010, 14:04   #3
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Caso pratico comune: @property, @staticmethod e @classmethod. Adesso sono incasinato, tu documentati. Quando posso casomai scrivo qualche esempio.
In generale, quando hai bisogno di modificare o fare operazioni su una funzione, allora i decoratori fanno al caso tuo. Ovviamente non se ne deve abusare e quello che fai con i decoratori lo puoi fare anche senza, però semplificano la vita in alcuni casi.
Esempio: mettiamo che hai scritto un'applicazione in Django e vuoi fare in modo che possa essere usata solo dall'admin. Puoi benissimo scriverti un decoratore che controlla se la vista richiesta sia stata "chiamata" dall'admin o no e quindi determinare le operazioni da seguire o sollevare un'eccezione.

Ultima modifica di Ryuzaki_Eru : 18-07-2010 alle 14:12.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 19-07-2010, 08:38   #4
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Un caso pratico, reale, e comunissimo è il log.

Mettiamo che debba loggare la chiamata a una funzione, i suoi parametri, e il valore di ritorno.

Scrivo un decoratore log che restituisce un wrapper che "ingloba" la funzione da chiamare. A questo punto quando il wrapper viene invocato, logga il nome della funzione che ha inglobato, e i parametri che gli sono stati passati. A questo punto richiama la funzione e conserva il risultato. Logga il risultato. E infine restituisce il valore al chiamante.

Per qualunque funzione (o metodo) da loggare basta scrivere:
Codice:
@log
def MiaFunzione(): pass
Semplice e pulito.

Ancora più interessanti sono i decoratori di classi. Si può scrivere un decoratore di classe (che è una funzione), che invece di ricevere in input una funzione, riceve una classe. A questo punto possiamo prendere l'elenco di tutti i suoi metodi e applicarci una decoratore di log, in modo che tutti i suoi metodi siano loggati.

Quindi per loggare tutti i metodi di una classe basta scrivere:
Codice:
@log
class MiaClasse():

def f(self): pass

def g(self): pass
Supposto che log sia la funzione di decorazione della classe, questa restituirà sempre la classe MiaClasse, ma con tutti i metodi di quest'ultima che saranno loggati.

Comunque complimenti per la guida: chiara e semplice. Se aggiungi i decoratori di classe (disponibili da Python 2.6) secondo me potrebbe essere messa nella sezione dei tutorial.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 19-07-2010, 10:28   #5
Torav
Senior Member
 
Iscritto dal: Dec 2005
Messaggi: 558
Ottima guida, grazie mille!
Torav è offline   Rispondi citando il messaggio o parte di esso
Old 19-07-2010, 15:26   #6
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Quote:
Comunque complimenti per la guida: chiara e semplice. Se aggiungi i decoratori di classe (disponibili da Python 2.6) secondo me potrebbe essere messa nella sezione dei tutorial.
La guida l'avevo scritta per il mio blog, poi ho chiesto a cionci che mi ha detto che andava bene per la sezione tutorial e cosi l'ho "modificata".
Comunque è un argomento interessante questo dei decoratori di classe. Appena posso l'aggiungo
Se vuoi puoi anche aggiungere tu degli esempi alla tua spiegazione che hai appena scritto e il 90% è già praticamente fatto
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 19-07-2010, 17:27   #7
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Quote:
Originariamente inviato da Ryuzaki_Eru Guarda i messaggi
Caso pratico comune: @property, @staticmethod e @classmethod.
Ecco, bravo, fai qualche esempio con le classi "nuovo stile", discendenti di object.

ciao, e complimenti per il lavoro
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 19-07-2010, 18:53   #8
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Ecco, bravo, fai qualche esempio con le classi "nuovo stile", discendenti di object.

ciao, e complimenti per il lavoro
Aggiungerò un esempio anche con questi
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 19-07-2010, 22:35   #9
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Quote:
Originariamente inviato da Ryuzaki_Eru Guarda i messaggi
La guida l'avevo scritta per il mio blog, poi ho chiesto a cionci che mi ha detto che andava bene per la sezione tutorial e cosi l'ho "modificata".
Comunque è un argomento interessante questo dei decoratori di classe. Appena posso l'aggiungo
Se vuoi puoi anche aggiungere tu degli esempi alla tua spiegazione che hai appena scritto e il 90% è già praticamente fatto
Eccolo qui l'esempio:
Codice:
from functools import wraps

def log(Function):
  'Decorator to log a function call, its parameters, and its result'

  @wraps(Function)
  def Wrapper(*Args, **Keywords):

    print Function.__name__, Args, Keywords

    Result = Function(*Args, **Keywords)

    print Function.__name__, '->', Result

    return Result

  return Wrapper


@log
def f(x, y, z):
    return x * y * z

f(1, 2, 3)


@log
def g(*Args, **Keywords):
    return 'Argomenti: %s. Keyword: %s.' % (Args, Keywords)

g(1, 2, 3, y = 'a', z = 'b', x = 'c')
E questo è il risultato:
Codice:
f (1, 2, 3) {}
f -> 6
g (1, 2, 3) {'y': 'a', 'x': 'c', 'z': 'b'}
g -> Argomenti: (1, 2, 3). Keyword: {'y': 'a', 'x': 'c', 'z': 'b'}.
Questo decoratore stampa a video, ma basta modificarlo per poter scrivere tutte le informazioni su file, db, ecc., senza andare a toccare le funzioni che "decora".

Ne uso altri anche per validare l'input, oppure per intercettare eventuali eccezioni.

Coi decoratori c'è ampio spazio per l'immaginazione.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 20-07-2010, 12:00   #10
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Bene, poi lo aggiungo alla guida con i riferimenti a te. Appena posso scrivo degli esempi con @property, @staticmethod e @classmethod, e un esempio di decoratore di classe.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 21-07-2010, 10:18   #11
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Lascia perdere i riferimenti a me.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 21-07-2010, 10:19   #12
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
L'hai scritto tu quel pezzo, è giusto che metto i riferimenti
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 21-07-2010, 21:49   #13
nardellu
Senior Member
 
L'Avatar di nardellu
 
Iscritto dal: Apr 2005
Città: SARDEGNA
Messaggi: 1861
ottima spiegazione complimenti!

la prima volta che mi sono imbatutto su un decorator è stato su django... @login_required

fortuna che ho intuito al volo la loro funzione!
__________________
Trattative OK non le conto più...Trattative non OK: Slashdot giuscone Kururu Paki deCri
nardellu è offline   Rispondi citando il messaggio o parte di esso
Old 01-08-2010, 10:38   #14
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Al più presto aggiorno la guida, scriverò degli esempi sui decoratori predefiniti in Python e vedrò di fare smanettare sui decoratori di classe che sono particolari, anche se il funzionamento e il concetto è identico a quelli delle funzioni.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 19-05-2011, 09:14   #15
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Noto che la guida non è stata ancora spostata nell'apposita sezione...come mai?
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 19-05-2011, 13:58   #16
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Forse cionci aspetta che completi l'argomento coi decoratori di classe.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 19-05-2011, 14:05   #17
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Forse cionci aspetta che completi l'argomento coi decoratori di classe.
Al momento la vedo difficile...se qualcuno lo vuole completare(se il problema è questo) per me va bene. Altrimenti c'è da aspettare un pò.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 19-05-2011, 14:18   #18
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Allora aspetteremo. Comunque per un'introduzione ai decoratori quanto già scritto va bene.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 20-05-2011, 09:20   #19
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4131
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Allora aspetteremo. Comunque per un'introduzione ai decoratori quanto già scritto va bene.
Anche perchè dopo tutto questo tempo fermo devo fare una bella rispolverata di tutto.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Roborock Qrevo Curv 2 Flow: ora lava con un rullo Roborock Qrevo Curv 2 Flow: ora lava con un rull...
Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite Alpine A290 alla prova: un'auto bella che ti fa ...
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile Recensione HONOR Magic 8 Lite: lo smartphone ind...
Sony WF-1000X M6: le cuffie in-ear di riferimento migliorano ancora Sony WF-1000X M6: le cuffie in-ear di riferiment...
Snowflake porta l'IA dove sono i dati, anche grazie a un accordo con OpenAI Snowflake porta l'IA dove sono i dati, anche gra...
Oracle NetSuite si potenzia con nuove fu...
Musica generata con l'IA: Sony lavora a ...
Cyberpunk 2077 in versione PC su smartph...
BYD si gioca un grosso jolly: pronta Rac...
Samsung annuncia l'arrivo in Italia dei ...
Offerta lancio Pixel 10a: come ottenere ...
Google presenta Pixel 10a: poche le novi...
Caos F1 2026: 14 monoposto senza omologa...
Tesla festeggia il primo Cybercab prodot...
Desktop piccolo e potente? NZXT H2 Flow ...
Polestar spinge sull'acceleratore: arriv...
Nuovo record mondiale nel fotovoltaico: ...
L'ultimo baluardo cade: fine supporto pe...
'Il mondo non ha mai visto nulla di simi...
La Commissione europea mette sotto indag...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 20:11.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v