2012-10-04 20 views
47

Desidero creare un tipo di classe di utilità che contenga solo metodi statici richiamabili dal prefisso della classe nome. Sembra che sto facendo qualcosa di sbagliato :)Metodi statici di classe Python

Qui è la mia piccola classe:

class FileUtility(): 

    @staticmethod 
    def GetFileSize(self, fullName): 
     fileSize = os.path.getsize(fullName) 
     return fileSize 

    @staticmethod 
    def GetFilePath(self, fullName): 
     filePath = os.path.abspath(fullName) 
     return filePath 

Ora il mio metodo "main":

from FileUtility import * 
def main(): 
     path = 'C:\config_file_list.txt' 
     dir = FileUtility.GetFilePath(path) 
     print dir 

e ho ottenuto un errore: unbound method GetFilePath() must be called with FileUtility instance as first argument (got str instance instead).

A hanno alcune domande qui:

  1. Che cosa sto facendo di sbagliato? Il metodo statico non dovrebbe essere chiamato per nome di classe?
  2. Ho davvero bisogno di una classe di utilità, o ci sono altri modi per ottenere lo stesso risultato in Python?
  3. Se provo a cambiare il codice principale sto ottenendo: TypeError: GetFilePath() takes exactly 1 argument (2 given)

Il nuovo main:

from FileUtility import * 
def main(): 
    objFile = FileUtility() 
    path = 'H:\config_file_list.txt' 
    dir = objFile.GetFilePath(path) 
    print dir 

risposta

82

Stai diventando l'errore perché si sta prendendo un argomento self in ciascuna di queste funzioni. Sono statici, non ne hai bisogno.

Tuttavia, il modo "pythonic" di fare ciò non è di avere una classe piena di metodi statici, ma semplicemente di renderli funzioni libere in un modulo.

#fileutility.py: 

def get_file_size(fullName): 
    fileSize = os.path.getsize(fullName) 
    return fileSize 


def get_file_path(fullName): 
    filePath = os.path.abspath(fullName) 
    return filePath 

Ora, in altri file python (supponendo fileutility.py si trova nella stessa directory o sul PYTHONPATH)

import fileutility 

fileutility.get_file_size("myfile.txt") 
fileutility.get_file_path("that.txt") 

Non menziona metodi statici in particolare, ma se siete provenendo da una lingua diversa, PEP 8, la guida allo stile di Python è una buona lettura e introduzione a come pensano i programmatori Python.

+0

Hi Collin, grazie per la risposta, ho fatto come lei ha suggerito, file di pitone pianura con elenco dei metodi e nelle principali: dir = FileUtility.GetFilePath (percorso) Ho ricevuto un errore: metodo GetFilePath() non associato deve essere chiamato con l'istanza FileUtility come primo argomento (ottenuto invece istanza str) – ilyaw77

+0

Scusa, lasciato un auto randagio lì dentro alla prima esecuzione. Hai ancora una classe FileUtility da qualche parte? – Collin

+1

Il punto è che non dovresti avere una FileUtility di classe. Proprio come potresti scrivere funzioni libere in C++, dovresti fare lo stesso qui. I nomi dei moduli (che mappano ai file) dovrebbero essere tutti in minuscolo. – Collin

8

davvero non dovrebbe essere la creazione di metodi statici in Python. Quello che dovresti fare è metterli a livello di funzione globale e quindi accedere al modulo in cui si trovano quando li chiami.

foo.py:

def bar(): 
    return 42 

baz.py:

import foo 
print foo.bar() 
4

In Python, Java-like (o qualsiasi altra cosa) static metodi non sono ampiamente utilizzati come in realtà non hanno un scopo.

Invece, si dovrebbe semplicemente definire i "metodi" come funzioni in un modulo:

#module1.py 
def fun1(): 
    return do_stuff() 
def fun2(arg): 
    return do_stuff_with_arg(arg) 

#main.py 
import module1 
if __name__ == '__main__': 
    a = module1.fun() 
    print module1.fun2(a) 
6

I metodi statici non ottengono l'oggetto passato come primo parametro (senza oggetto)

rimuovere il parametro self e le chiamate dovrebbe funzionare. Anche il problema dell'importazione è rilevante. E anche il commento statico è rilevante.

1

Se si desidera utilizzare le funzioni definite nella classe, è sufficiente creare un'istanza della classe e applicare la funzione.

Così il risultato è:

dir = FileUtility().GetFilePath(path) 

Just Add() dopo il nome della classe.

@staticmethod non è necessario in quanto si utilizza la funzione standard, non statica. Ma nel tuo caso il risultato è lo stesso.

2

Basta rimuovere self nella definizione dei metodi. La tua intenzione è quella di usare come statico. Il Sé è lavorare con l'istanza di quella classe.

0

Basta rimuovere il sé nella definizione della funzione. Poiché utilizzi le funzioni statiche, non è necessario passare il self come argomento per le funzioni. Così la classe e la funzione dovrebbe essere come questo:

class FileUtility(): 

    @staticmethod 
    def GetFileSize(fullName): 
     fileSize = os.path.getsize(fullName) 
     return fileSize 

    @staticmethod 
    def GetFilePath(fullName): 
     filePath = os.path.abspath(fullName) 
     return filePath