Trzymanie wszystkiego w klasie "Root". Czy to jest poprawne.

0

Cześć.
Umieściłem wszystko w klasie "rodzica". Nawet nowy obiekt tworzy się jako element słownika umieszczonego w klasie "rodzica".
Czy takie coś ma sens czy tylko sztuka dla sztuki. W sumie to nawet chyba nie w instancji tylko w samej klasie.
Dopiero poznaję klasy bo jakoś nie jestem do nich przekonany.

class Root():
	nrID=-1
	dObj={}
	level=0

	def mIdUp(self):
		__class__.nrID+=1
		return __class__.nrID

	def mLen(self):
		return len(__class__.lObj)

	def mPrint(self):
		print()
		dDict=__class__.dObj
		for obj in dDict.keys():
			print(obj,'->',vars(dDict[obj]))
		return None
	
	def mVars(self):
		return vars(self)

	def mAddChild(self):
		try:
			nDlaId=int(input("Dla jakiego id?: "))
		except:
			print('\n\t\t\tId musi być INT!')
			return None
		if nDlaId in __class__.dObj:
			oB=__class__.dObj[nDlaId] #.mVars()
			if 'childrensIds' in oB.mVars():
				sName=input('Podaj imię: ')
				newId=self.mIdUp()
				while newId in __class__.dObj.keys():
					newId+=1
				nextLevel=oB.mVars()['level']+1
				__class__.dObj[newId]=Node(sName,nDlaId,nextLevel)
				oB.mVars()['childrensIds'].append(newId)
			else: print("Ten węzeł nie może mieć dzieci")
		else: print('Brak takiego id!')
		return None

class Node(Root):
	def __init__(self,name,parentId,level):
		self.name=name
		self.parentId=parentId
		self.childrensIds=[]
		self.level=level
		return None

# making ROOT
Root().dObj[0]=Node('GRoot',None,0) # name,parent id, level

sKey=''
while sKey!='ex':
	sKey=input('\nex - przerwij\nw - wypisz l.by l.\nc - dodaj dziecko\np - wypisz RAW\n\tWybierz opcję: ')
	if sKey=='w': Root().mPrint()
	if sKey=='c': Root().mAddChild()
	if sKey=='p': print("\n",Root().dObj)

Pozdrawiam
Radosław Głębicki

1

Co tu się w ogóle dzieje? Jaki problem rozwiązujesz?

1

To nie jest dobra praktyka. Twoja klasa łamie zasadę Single Responsibility Principle.

Pozdrawiam,
Twój Stary Pijany

0

Czemu nie coś takiego?

class NodeSet(dict):
    def add_node(self, node):
        self[node.name] = node

    def add_child(node_set):
        parent_name = input('podaj imię rodzica')
        child_name = input('podaj imię dziecka')
        child = Node(child_name, node_set[parent_name])
        node_set[parent_name].add_child(child)

class Node:
    def __init__(self, name, parent):
        self.name=name
        self.parent = parent
        self.children = []
    def add_child(self, child):
        self.children.append(child)
    def __str__(self):
        return f"Node(name={self.name}, children={[str(c) for c in self.children]})"
    def __repr__(self):
        return str(self)


def main():
    node_set = NodeSet()
    node_set.add_node(Node('Groot', None))

    sKey = ''
    while sKey != 'ex':
        sKey = input('\nex - przerwij\nw - wypisz l.by l.\nc - dodaj dziecko\n\tWybierz opcję: ')
        if sKey == 'w': print(node_set)
        if sKey == 'c': node_set.add_child()

if __name__ == '__main__':
    main()
0

Ten kod jest jakiś nieczytelny. Może też kwestia, że nie programuję na codzień w Pythonie i nie do końca wiem, co tam się dzieje ( __class__.dObj oznacza odwoływanie się do jakiejś zmiennej statycznej dObj aktualnej klasy?), ale i tak obstawiam, że nie tylko dla mnie to będzie WTF.

  1. kryptyczne nazwy i chyba tu stosujesz notację węgierską (m to znaczy metoda? d to znaczy data?). Przez to trzeba się zastanawiać, o co tu chodzi. Albo zmienna po polsku nDlaId. Albo childrensIds też wygląda dziwacznie z tym s na końcu.
  2. def mAddChild to metoda, która robi wszystko:
  • pobiera input od użytkownika (to między try i except), czyli wejście.
  • sprawdza jakieś tajemnicze warunki robi jakąś tajemniczą pętlę (to wygląda jak dodawanie jakichś danych do słownika w odpowiednim miejscu), czyli jak rozumiem zapisywanie danych.
    • i tutaj niestety znowu mamy jakieś dziwne cuda, bo znowu pobieramy input od użytkownika tak out of blue jest sName=input('Podaj imię: ')

Czyli masz jeden wielki burdel w metodzie mAddChild. Dodawanie nowych węzłów jest sklejone z inputem od użytkownika. Czyli nie możesz zrobić jednej rzeczy naraz (np. dodać węzeł, ale bez potrzeby, żeby użytkownik coś wpisywał).

  1. jakaś dziwna logika. Może ja nie rozumiem zaawansowanego Pythona, ale dla mnie to wygląda jak partyzantka, sposób w jaki trzymasz i odwołujesz się do danych (__class__, vars(self)). Jak dla mnie to takie metapisanie dla samego metapisania. Ja nie wiem, co się tam dzieje, gdzie ty trzymasz te dane. A mówią, że Python jest czytelny.

  2. po co jest podklasa Node? Tylko po to, żeby zainicjalizować zmienne? Tego też nie rozumiem

0

"Gdzie ty trzymasz te dane". O to właśnie pytam czy ten sposób przechowywania obiektów ma sens. Bez zewnętrznych zmiennych/list. Wszystko wewnątrz klasy Root. Klasa potomna Node służy właśnie do dodania kolejnego węzła. Ale faktycznie opis zmiennych typu: class.zmienna jest brzydki. To nie jest zaawansowany Python. Cel był jeden - brak zewnętrznych zmiennych. Pytam o opinię czy taki sposób jest dobry, bezpieczniejszy niej pamięciożerny. Nie wiem co jeszcze. Najdziwniejsze, że mi się podoba. Jest nieźle pokręcone. ;-D Do tej pory wszystkie moje wypociny były pisane z wykorzystaniem funkcji. Tkinter, pyqt5 czy nawet Kivy. Ani jednej klasy.

A jeszcze jeśli chodzi o mAddChildren. Pobieranie danych zabrać stamtąd? I gdzie dać?
Lubię dodawać m lub f bo napisałem sobie dodatek do edytora Kate, który filtruje mi po 'def m' lub 'def f'. Klikam i szybko się przenoszę. Taka nawigacja.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.