Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Zenfone 11 Ultra: il flagship ASUS ritorna a essere un 'padellone'
Recensione Zenfone 11 Ultra: il flagship ASUS ritorna a essere un 'padellone'
Zenfone 11 Ultra ha tantissime qualità interessanti, fra cui potenza da vendere, un display di primissimo livello, un comparto audio potente e prestazioni di connettività fra le migliori della categoria. Manca però dell'esclusività del predecessore, che in un settore composto da "padelloni" si distingueva per le sue dimensioni compatte. Abbiamo provato il nuovo flagship ASUS, e in questa recensione vi raccontiamo com'è andata.
Appian: non solo low code. La missione è l’ottimizzazione dei processi con l'IA
Appian: non solo low code. La missione è l’ottimizzazione dei processi con l'IA
Abbiamo partecipato ad Appian World 2024, evento dedicato a partner e clienti che si è svolto recentemente nei pressi di Washington DC, vicino alla sede storica dell’azienda. Nel festeggiare il 25mo anniversario, Appian ha annunciato diverse novità in ambito intelligenza artificiale
Lenovo ThinkVision 3D 27, la steroscopia senza occhialini
Lenovo ThinkVision 3D 27, la steroscopia senza occhialini
Primo contatto con il monitor Lenovo ThinkVision 3D 27 che grazie a particolari accorgimenti tecnici riesce a ricreare l'illusione della spazialità tridimensionale senza che sia necessario utilizzare occhialini
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 18-07-2010, 10:48   #1
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
[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 11:01.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2010, 12:29   #2
das
Senior Member
 
Iscritto dal: Jan 2001
Città: Livorno
Messaggi: 1275
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, 13:04   #3
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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 13:12.
Ryuzaki_Eru è offline   Rispondi citando il messaggio o parte di esso
Old 19-07-2010, 07:38   #4
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
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, 09: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, 14:26   #6
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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, 16:27   #7
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5964
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, 17:53   #8
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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, 21:35   #9
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
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, 11:00   #10
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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, 09:18   #11
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
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, 09:19   #12
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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, 20: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, 09:38   #14
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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, 08:14   #15
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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, 12:58   #16
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
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, 13:05   #17
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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, 13:18   #18
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
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, 08:20   #19
Ryuzaki_Eru
Senior Member
 
L'Avatar di Ryuzaki_Eru
 
Iscritto dal: Sep 2009
Città: Nel mondo dei sogni
Messaggi: 4125
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


Recensione Zenfone 11 Ultra: il flagship ASUS ritorna a essere un 'padellone' Recensione Zenfone 11 Ultra: il flagship ASUS ri...
Appian: non solo low code. La missione è l’ottimizzazione dei processi con l'IA Appian: non solo low code. La missione è ...
Lenovo ThinkVision 3D 27, la steroscopia senza occhialini Lenovo ThinkVision 3D 27, la steroscopia senza o...
La Formula E può correre su un tracciato vero? Reportage da Misano con Jaguar TCS Racing La Formula E può correre su un tracciato ...
Lenovo LEGION e LOQ: due notebook diversi, stessa anima gaming Lenovo LEGION e LOQ: due notebook diversi, stess...
La Cina ha lanciato la missione Shenzhou...
La sonda spaziale NASA Psyche comunica v...
Dacia Duster, prima guida: con le versio...
Google Pixel 8 Pro 256 GB a 928€ (minimo...
Arriva l'ok da Parlamento europeo sul di...
RISC-V: l'uso dell'ISA open-source da pa...
Amazon scatenata: iPad a 399€, airfryer ...
SK hynix, costruzione della Fab M15X ai ...
Oggi 459€ per utenti Prime il portatile ...
Sta per succedere! La prima gara a guida...
Parthenope: un nuovo RPG investigativo t...
Urbanista Malibu: ecco come va la cassa ...
Gas Station Simulator è costato 1...
AOC Graphic Pro U3, tre nuovi monitor pe...
Wacom Movink: per la prima volta il disp...
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: 03:24.


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