[Python]Jak poprawnie zwracać dane z metody?

0

Cześć mam mega newbie pytanie , ale .. czuję że coś mi się miesza

mam klasę w pythonie:

class Foo(object):
    atrybut1 = []
    dict_file_details = {}
    file_name = ()
    file_type = ()
    def Bar(self):
        tmp_list={}
        file_name = ("file_name","/etc") # tutaj jest przypisywany wynik funkcji
        file_type = ('file_type', 'directory') # jak ww
        ...
        tmp_list['file_details'] = [file_name, file_type]

Pytanie:

  1. Chciałbym żeby funkcja Bar zwracała listę i troszkę miesza mi się temat hermetyzacji .. wiem, to podstawy, ale wydaję mi się, że potrzebuję krótkiej i zwięzłej informacji jaką zasadą się kierować podczas pisania klas/metod. Powinienem zrobić tak?:
    ```python
    def Bar(self):
    tmp_list={}
    file_name = ("file_name","/etc") # tutaj jest przypisywany wynik funkcji
    file_type = ('file_type', 'directory') # jak ww

              tmp_list['file_details'] = [file_name, file_type]
              return tmp_list 
      ```
    

    czy tak:
    ```python
    def Bar(self):
    self.file_name = file_name_a = ("file_name","/etc") # tutaj jest przypisywany wynik funkcji
    self.file_type = file_type_b = ('file_type', 'directory') # jak ww

              self.dict_file_details['file_details'] = [file_name_a, file_type_b] # czy może zamiast file_name_a, file_type_b, powinienem uzyć bezpośrednio self.file_name,self.file_type 
              return self.dict_file_details 
    ```
    

2.Jaką zasadą się kierować , gdy inicjalizacje puste zmienne. Na razie kieruje się tym, jaki typ danych ma tam ostatecznie trafić czyli jak wiem, ze będzie lista , to tworze listę itd.

0

Masz tu mess, tmp_list = {}, słowik Nazywasz tmp_list, file_name = ("file_name","/etc"), co to znaczy, że jest tu przypisywany wynik funkcji. A jeśli chodzi o hermetyzację, to sposób pierwszy jest jej bliższy, nie modyfikuje i nie wystawia na widok publiczny wewnętrznych pól; ale być może źle myślę, może Chcesz zmieniać stan wewnętrzny. Trochę więcej szczegółów by się przydało.

0

Faktycznie , nie zauważyłem .. teraz mam taką klase

class Get_file_detail(object):
    file_detail_dict = {}
    file_name = ()
    file_type = ()

    def get_file_details(self, file):
        tmp_arr = []

        self.file_name = subprocess.run("stat -c %n /{}".format(file), shell=True, capture_output=True,universal_newlines=True)  # -file name
        self.file_type = subprocess.run("stat -c %F /{}".format(file), shell=True, capture_output=True,universal_newlines=True)  # -file type

        tmp_arr.append( ("file_name", self.file_name.stdout.strip("\n")) )
        tmp_arr.append( ("file_type", self.file_type.stdout.strip("\n")) )
        self.file_detail_dict['file_details'] = tmp_arr


    def get_files_detail_dict(self):
        """ return dict"""
        return self.file_detail_dict

    def get_file_name(self):
        return self.file_name

    def get_file_type(self):
        return self.file_type

Problem w tym, ze nie wiem jaki pracować z atrybutami. Czy klasa powinna udostępniać metody get_ i set_, do dostępu do atrybutów klasy?
Czy jeśli metoda ma zwracać jakąś wartość np. listę to, czy powinienem utworzyć najpierw atrybut klasy odpowiadający tej liście, zrobić do niej przypisanie i następnie zwrócić , czy stworzyć zmienną lokalną dla metody i zwracać zmienną lokalną.. zawsze się z tym borykam ..

Na razie nie rozważam używania atrybutów prywatnych, ale to już po raz kolejny gdy się rozbijam o ten problem. Może macie jakieś swoje reguły/zasady którymi się kierujecie i się tego sztywno trzymacie?

edit

Kolejny problem który się pojawił. Co gdy będę chciał użyć metody get_file_details() do większej ilość plików , co wymusi użycie pętli. Zakładam , że trzeba będzie zrobić nowa metodą, która nie wypełnia atrybutów.

0

Czy klasa powinna udostępniać metody get i set, do dostępu do atrybutów klasy?

Nie, nie powinna, ale Tworzysz sobie problemy do rozwiązania na inna okazję:). Przeież można zdefiniować funkcję:

def get_file_details(file):
	tmp_arr = []
	file_detail_dict = dict()
	file_name = subprocess.run("stat -c %n /{}".format(file), shell=True, capture_output=True,universal_newlines=True)  # -file name
	file_type = subprocess.run("stat -c %F /{}".format(file), shell=True, capture_output=True,universal_newlines=True)  # -file type
	tmp_arr.append( ("file_name", file_name.stdout.strip("\n")) )
	tmp_arr.append( ("file_type", file_type.stdout.strip("\n")) )
	file_detail_dict['file_details'] = tmp_arr
	return file_detail_dict

W tym słowniku, są już wszystkie dane, nie trzeba oddzielnych funkcji; łatwo też będzie Ci to zrefaktorować na funkcję przyjmującą listę plików.

0
lion137 napisał(a):

Czy klasa powinna udostępniać metody get i set, do dostępu do atrybutów klasy?

Nie, nie powinna, ale Tworzysz sobie problemy do rozwiązania na inna okazję:). Przeież można zdefiniować funkcję:

def get_file_details(file):
	tmp_arr = []
	file_detail_dict = dict()
	file_name = subprocess.run("stat -c %n /{}".format(file), shell=True, capture_output=True,universal_newlines=True)  # -file name
	file_type = subprocess.run("stat -c %F /{}".format(file), shell=True, capture_output=True,universal_newlines=True)  # -file type
	tmp_arr.append( ("file_name", file_name.stdout.strip("\n")) )
	tmp_arr.append( ("file_type", file_type.stdout.strip("\n")) )
	file_detail_dict['file_details'] = tmp_arr
	return file_detail_dict

W tym słowniku, są już wszystkie dane, nie trzeba oddzielnych funkcji; łatwo też będzie Ci to zrefaktorować na funkcję przyjmującą listę plików.

Ok, dzięki za pomoc :). Wygląda na to, że przypisuje jedną z funkcji konstruktora tj. inicjalizacja danych początkowych do innych metod tej samej klasy.

Mam jeszcze kilka funkcji , które zwracają dane w identycznym formacie co ten DICT i chciałbym wygenerować z tych klas 1 raport, orientujesz się może, jaki wzorzec był by to tego najlepszy ? może singleton ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1