Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Python - Jak mít uložené metody třídy v jiném souboru

Ahoj, mám v Pythonu třídu, ve které volám metody pomocí self. Existuje způsob, jak udržet volání metod pomocí self a přitom by všechny volané metody byly v samostatném souboru?
- jedna metoda == jeden soubor
- všechny metody by se volaly mezi sebou přes self
- metody by zůstaly i nadále součástí třídy MyClass

class MyClass:
	def __init__(self):
		self.method_one()
		self.method_two()
	def method_one(self):
		pass
	def method_two(self):
		pass
MyClass()

Díky za informaci

Předmět Autor Datum
To zavání dost špatným návrhem třídy.
Wikan 27.02.2022 19:34
Wikan
V ramci volani metody jen v implementaci zavolat funkci/proceduru z jineho souboru.
Jan Fiala 27.02.2022 20:05
Jan Fiala
U takhle malé třídy to nemá smysl, ale ono to nemá smysl ani u třídy, která má těch řádků docela hod…
gilhad 28.02.2022 19:17
gilhad
Dyť jen voláš v každé metodě další funkci. To si můžu ty metody rovnou sourcnout do té class a ušetř…
pman 01.03.2022 20:31
pman
jen to chce dotáhnout syntakticky ( tady pomocí from ... import ... as ... ) class MyClass: def __i…
gilhad 02.03.2022 09:18
gilhad
Jenže takový zápis nic neřeší, jak jsem psal, potřebuji aby se to chovalo jako metoda uvnitř class,…
pman 02.03.2022 10:09
pman
A co teda chceš, aby to řešílo? Psal jsi - co metoda, to soubor - OK - ale samozřejmě pokud máš tunu…
gilhad 02.03.2022 14:35
gilhad
Dejme tomu, že mám Soubor main.py import time class MyClass: def __init__(self): self.method_one()…
pman 02.03.2022 21:50
pman
IMPORT nevkládá text, ale zavádí modul, takže ty závislosti někde mít musíš tak, aby se na to ty mod…
gilhad 02.03.2022 23:26
gilhad
Díky za objasnění, existuje něco místo importu co ten kód načte a vykoná se až po načtení?
pman 03.03.2022 14:23
pman
Už jsem to našel, tohle funguje, ale editor to stejně označí jako chybu tak je to spíš nepoužitelné…
pman 03.03.2022 15:42
pman
Tohle ale taky řádky nevloží, nýbrž načte soubor (který tam nemáš uvedený) a vykoná ho. https://docs… poslední
gilhad 03.03.2022 22:41
gilhad

U takhle malé třídy to nemá smysl, ale ono to nemá smysl ani u třídy, která má těch řádků docela hodně (tím myslím třeba i stovku nebo dvě na metodu - pokud jich je víc, tak je to nejspíš špatný návrh).

Samozřejmě je VELMI DOBRÉ používat nějaké rozumné FOLDOVÁNÍ, protože obecně bys neměl mít konstrukci, která se při práci nevejde na jednu obrazovku, nejhůř na dvě. (jo, mám soubory s 2k+ řádky a taky tam to pravidlo dodržuju ).

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

Ale pokud to jinak nejde, tak můžeš (ale je to FAKT ŠPATNÉ) použít třeba něco jako

MyClass_method_one_python.py:


def MyClass_method_one(self, a, b, c):
	self.method_two(a,b,c)

MyClass_method_two_python.py:


def MyClass_method_two(self, a, b, c):
	self.method_three(a,b,c)

MyClass_python.py:


from  MyClass_method_one_python import MyClass_method_one
from  MyClass_method_two_python import MyClass_method_two
#....
class MyClass:
	def __init__(self):
		self.method_one(1,2,3)
		self.method_two(4,5,6)
	def method_one(self, a, b, c):
		MyClass_method_one(self, a, b, c)
	def method_two(self, a, b, c):
		MyClass_method_two(self, a, b, c)
	def method_three(self, a, b, c):
		print( a, b, c)
#.....
MyClass()

ale je to stejně dost prasácký styl a v praxi přinese neskutečné množství podivných problémů

Dyť jen voláš v každé metodě další funkci. To si můžu ty metody rovnou sourcnout do té class a ušetřím tak půlku řádků.


class MyClass:
	def __init__(self):
		self.method_one(1,2,3)
		self.method_two(4,5,6)
	from  MyClass_method_one_python import MyClass_method_one
	from  MyClass_method_two_python import MyClass_method_two

jen to chce dotáhnout syntakticky ( tady pomocí from ... import ... as ... )

class MyClass:
	def __init__(self):
		self.method_one(1,2,3)
		self.method_two(4,5,6)
	from  MyClass_method_one_python import MyClass_method_one as method_one
	from  MyClass_method_two_python import MyClass_method_two as method_two
	def method_three(self, a, b, c):
		print( a, b, c)
MyClass()

Jenže takový zápis nic neřeší, jak jsem psal, potřebuji aby se to chovalo jako metoda uvnitř class, takto se kód vykoná vždy mimo tu class, čili musím do každé metody načítat tunu nesmyslných souborů i přesto, že jsou součástí class do které se ty metody načítají.

A co teda chceš, aby to řešílo?
Psal jsi
- co metoda, to soubor - OK - ale samozřejmě pokud máš tunu nesmyslných metod, tak z toho plyne tuna nesmyslných souborů a protože počítač není věštec, tak je také někdy musí načíst (a tady mu to stačí jednou pro každý soubor, ať už pak těch class uděláš kolik chceš)
- všechny metody by se volaly mezi sebou přes self - OK
- metody by zůstaly i nadále součástí třídy MyClass - OK

Kód se samozřejmě vykonává v kontextu dané instance třídy (ledaže bys ty metody definoval jako metody nikoli instance, ale přímo té třídy, pak by se vykonávaly samozřejmě přímo v kontextu třídy ).

Takže napiš příklad, jak by sis to asi tak představoval a jak tohle nefunguje, a pak ten příklad můžeme rozebrat a dotvořit.

***********************

MyClass_method_4_python.py:



print("loading MyClass_method_4_python.py")
@classmethod
def MyClass_method_4(klass, a, b, c):
	print(klass,a,b,c)


MyClass_method_one_python.py:



print("loading MyClass_method_one_python.py")
def MyClass_method_one(self, a, b, c):
	self.method_two(a,b,c)

MyClass_method_two_python.py:



print("loading MyClass_method_two_python.py")
def MyClass_method_two(self, a, b, c):
	self.method_three(a,b,c)

MyClass_python.py:



#!/usr/bin/python -u
# vim: fileencoding=utf-8:nomodified:nowrap:textwidth=0:foldmethod=marker:foldcolumn=4:ruler:showcmd:lcs=tab\:|- list:noexpandtab:nosmarttab:softtabstop=0:shiftwidth=0

print("loading MyClass_python.py")
from  MyClass_method_one_python import MyClass_method_one
from  MyClass_method_two_python import MyClass_method_two
#....
class MyClass:
	def __init__(self):
		self.method_one(1,2,3)
		self.method_two(4,5,6)
	def method_one(self, a, b, c):
		MyClass_method_one(self, a, b, c)
	def method_two(self, a, b, c):
		MyClass_method_two(self, a, b, c)
	def method_three(self, a, b, c):
		print( a, b, c)
#.....
MyClass()


pok2.py:



#!/usr/bin/python -u
# vim: fileencoding=utf-8:nomodified:nowrap:textwidth=0:foldmethod=marker:foldcolumn=4:ruler:showcmd:lcs=tab\:|- list:noexpandtab:nosmarttab:softtabstop=0:shiftwidth=0
print("loading pok2.py")
class MyClass:
	def __init__(self):
		self.method_one(1,2,3)
		self.method_two(4,5,6)
	from  MyClass_method_one_python import MyClass_method_one as method_one
	from  MyClass_method_two_python import MyClass_method_two as method_two
	def method_three(self, a, b, c):
		print( a, b, c)
	from MyClass_method_4_python import MyClass_method_4 as class_method_4

MyClass.class_method_4("abra","ka","dabra")

MyClass()

b = MyClass()
c = MyClass()

c.method_one("C", "metoda číslo :", 1 )
b.method_two("B", "metoda číslo :", 2 )


***********************

$ ./MyClass_python.py 
loading MyClass_python.py
loading MyClass_method_one_python.py
loading MyClass_method_two_python.py
1 2 3
4 5 6




$ ./pok2.py 
loading pok2.py
loading MyClass_method_one_python.py
loading MyClass_method_two_python.py
loading MyClass_method_4_python.py
<class '__main__.MyClass'> abra ka dabra
1 2 3
4 5 6
1 2 3
4 5 6
1 2 3
4 5 6
C metoda číslo : 1
B metoda číslo : 2

Dejme tomu, že mám


Soubor main.py

import time
class MyClass:
	def __init__(self):
		self.method_one()
		self.method_two()
	from  method_one import method_one
	from  method_two import method_two
MyClass()


Soubor method_one.py

import time
def method_one():
     time.sleep(1)

soubor method_two.py

import time
def method_two():
     time.sleep(1)

Pokud odstraním v souboru method_one.py a method_two.py import time, tak to nebude fungovat, přesto, že je to již v souboru main.py, tak co dělám špatně?

IMPORT nevkládá text, ale zavádí modul, takže ty závislosti někde mít musíš tak, aby se na to ty moduly dostaly.

Ale můžeš si udělat modul, který zavádí všechny závislosti a pak importovat jen ten modul.

Nebo si můžeš do té klasy odložit i ty funkce z modulu (všechny, nebo jen vybrané) a pak je používat z té klasy

MyClass_method_4_python.py:



print("loading MyClass_method_4_python.py")
@classmethod
def MyClass_method_4(klass, a, b, c):
	klass.time.sleep(1)
	print(klass,a,b,c)


MyClass_method_one_python.py:



print("loading MyClass_method_one_python.py")
def MyClass_method_one(self, a, b, c):
	self.time.sleep(1)
	self.method_two(a,b,c)

MyClass_method_two_python.py:



print("loading MyClass_method_two_python.py")
def MyClass_method_two(self, a, b, c):
	self.time.sleep(1)
	self.method_three(a,b,c)

MyClass_python.py:



#!/usr/bin/python -u
# vim: fileencoding=utf-8:nomodified:nowrap:textwidth=0:foldmethod=marker:foldcolumn=4:ruler:showcmd:lcs=tab\:|- list:noexpandtab:nosmarttab:softtabstop=0:shiftwidth=0
print("loading MyClass_python.py")
from  MyClass_method_one_python import MyClass_method_one
from  MyClass_method_two_python import MyClass_method_two
#....
class MyClass:
#	from time import sleep
	import time
	def __init__(self):
		self.method_one(1,2,3)
		self.method_two(4,5,6)
	def method_one(self, a, b, c):
		MyClass_method_one(self, a, b, c)
	def method_two(self, a, b, c):
		MyClass_method_two(self, a, b, c)
	def method_three(self, a, b, c):
		print( a, b, c)
#.....
MyClass()


pok2.py:



#!/usr/bin/python -u
# vim: fileencoding=utf-8:nomodified:nowrap:textwidth=0:foldmethod=marker:foldcolumn=4:ruler:showcmd:lcs=tab\:|- list:noexpandtab:nosmarttab:softtabstop=0:shiftwidth=0
print("loading pok2.py")
class MyClass:
	import time
	def __init__(self):
		self.method_one(1,2,3)
		self.method_two(4,5,6)
	from  MyClass_method_one_python import MyClass_method_one as method_one
	from  MyClass_method_two_python import MyClass_method_two as method_two
	def method_three(self, a, b, c):
		print( a, b, c)
	from MyClass_method_4_python import MyClass_method_4 as class_method_4

MyClass.class_method_4("abra","ka","dabra")

MyClass()

b = MyClass()
c = MyClass()

c.method_one("C", "metoda číslo :", 1 )
b.method_two("B", "metoda číslo :", 2 )

Tohle ale taky řádky nevloží, nýbrž načte soubor (který tam nemáš uvedený) a vykoná ho. https://docs.python.org/3/library/functions.html#exec

Aplikace se píšou tak, že se rozdělí na jednotlivé logické knihovny a importujou se ty knihovny, nikoli náhodné kusy kódu.

Knihovny se udržují příčetně malé a v rámci nich používám foldování, takže většina zdrojáku je sbalená a jsou vidět jen ty části, které je potřeba editovat (tedy třeba jen pár řádků z jedné metody v jednom viewportu a pár z druhé v jiném).

Což ostatně asi platí pro většinu jazyků (ať už různých asseblerů, nebo jazyků čtvrté generace - technické provedení různé, princip stejný).

Jinak aplikace s několika tisíci řádků ještě nejsou zdaleka ty velké.
Sám (osobně a singl) jsem napsal, odladil a provozoval aplikaci, co měla přez 560.000 řádků v pythonu (ostatní jazyky nepočítaje) a nebylo to nic nepředstavitelně velkého.
Samozřejmě to nebyl jeden megasoubor ale asi 75 balíčků přímo instalovatelných a spravovatelných (tedy updaty, hlídání verzí a závislostí a tak) systémem, přičemž většina z nich měla víc než jednu knihovnu a většina knihoven exportovala víc než jednu třídu.
(A samozřejmě k tomu navrch wiki pro dokumentaci, bugzilla pro trasování chyb a požadavků atd. atd.)

Zpět do poradny Odpovědět na původní otázku Nahoru