•toni2007
|
|
« : August 11, 2009, 20:02:15 » |
|
Am si eu o problema legata de python. Am 2 clase, sa zicem foo si bar. Vreau ca din interiorul clasei foo sa pot accesa clasa bar si invers. Doar ca daca fac asa : class foo (models.Model) : a = models.ForeignKey(bar)
class bar (models.Model) : a = models.ForeignKey(foo)
Imi da ca nu gaseste clasa bar. Cum fac ca sa imi mearga ?
|
|
|
Memorat
|
|
|
|
•sima_cotizo
|
|
« Răspunde #1 : August 11, 2009, 20:30:36 » |
|
Daca inteleg bine ce cauti (recursivitate indirecta in Py), incearca sa citesti aici, poate te ajuta.
|
|
|
Memorat
|
|
|
|
•toni2007
|
|
« Răspunde #2 : August 11, 2009, 20:41:23 » |
|
Nu chiar, nu vreau sa le import. Pur si simplu le am in aceeasi sursa, si vreau ceva care s-ar face cam asa in c++ : class a
class b { int ceva; public b () { a aa; printf("%d", aa.ceva); } }
class a { int ceva; public a () { b bb; printf("%d", bb.ceva); } }
Da, un fel de recursivitate indirecta.
|
|
|
Memorat
|
|
|
|
•sima_cotizo
|
|
« Răspunde #3 : August 11, 2009, 20:58:14 » |
|
Pai citeste tot mesajul. Ei zic ca nu se poate direct si iti sugereaza sa faci 2 "base classes" din care sa le derivezi pe cele de care ai tu nevoie... (am dat peste rezultatul ala pe google cu "python indirect recursion", poate gasesti ceva mai detaliat).
|
|
|
Memorat
|
|
|
|
•toni2007
|
|
« Răspunde #4 : August 11, 2009, 21:42:47 » |
|
Cam asta imi trebuia, dar daca nu merge o sa incerc altfel.
|
|
|
Memorat
|
|
|
|
•bogdan2412
|
|
« Răspunde #5 : August 12, 2009, 17:06:11 » |
|
Daca folosesti Django, cum cred eu, poti sa faci a = models.ForeignKey("bar") in prima clasa.
|
|
« Ultima modificare: August 13, 2009, 14:19:23 de către Bogdan Tataroiu »
|
Memorat
|
|
|
|
•toni2007
|
|
« Răspunde #6 : August 13, 2009, 21:50:03 » |
|
Da, pentru Django aveam nevoie, imi merge. Mersi mult .
|
|
|
Memorat
|
|
|
|
•sandyxp
Strain
Karma: -1
Deconectat
Mesaje: 39
|
|
« Răspunde #7 : Septembrie 02, 2009, 12:16:11 » |
|
Intr-adevar, poate iti merge cum a zis bogdan, dar exemplul tau din py nu face acelasi lucru cu cel din C++, unde instantiezi un a() respectiv b() in constructor, si nu static. Cred ca de fapt vreu sa faci class foo(models.Model): def __init__(self): # constructor self.a = models.ForeignKey(bar)
class bar(models.Model): def __init__(self): self.a = models.ForeignKey(foo)
foo() bar()
in fiecare atribuire din __init__, foo sau bar sunt cautate local apoi global, adica apartinand modulei, unde vor fi gasite. Dar important e ca vor fi cautate de-abia la instantiere, cand clasele vor exista deja.
|
|
|
Memorat
|
|
|
|
•bogdan2412
|
|
« Răspunde #8 : Septembrie 02, 2009, 18:23:54 » |
|
Exemplu din C e diferit de ce vroia sa faca in python. Alea sunt modele de baze de date din Django si functioneaza un pic mai dubios decat clasele normale de python. Proprietatile clasei sunt folosite pentru a determina tipul coloanei in tabelul de baza de date si instanta primeste pentru fiecare proprietate valoarea din tabel. Adica proprietatile instantei nu o sa fie tot un models.ForeignKey, ci o valoare efectiva. Daca nu incerci sa intelegi cum merg pe dinauntru sunt foarte usor de folosit Exemplu din C intr-adevar se implementeaza cum ai zis tu.
|
|
|
Memorat
|
|
|
|
•toni2007
|
|
« Răspunde #9 : Septembrie 03, 2009, 14:24:30 » |
|
Am facut cum a zis Bogdan si a mers. Acum am alta problema : am un script intr-un director, numit grader.py. Am un director contest in acel director, iar in directorul contest, pun pt fiecare concurs cate un alt folder, cu numele concursului, in care o sa se afle un fisier <nume-concurs>-config.py. Eu vreau ca din grader.py sa includ pt un anumit concurs dat ca parametru, contests/<nume-concurs>/<nume-concurs>-config.py. Cum s-ar face asta in python ? Tot ce vreau e sa incarc cele 2 variabile (studs si probs) din <nume-concurs>-config.py (sa le pot accesa din grader.py, dupa ce includ scriptul <nume-concurs>-config.py.
|
|
|
Memorat
|
|
|
|
•peanutz
|
|
« Răspunde #10 : Septembrie 04, 2009, 15:01:56 » |
|
Poate ar fi mai bine sa-l numesti altcumva, nu config, poate sunt ceva module deja existente si n-o sa mearga.(chiar un nume dinamic in cazul tau) Daca ai avea scriptul configx.py in acelasi director merge sa-l incluzi direct cu from configx import *
si poti accesa clasele si variabilele specificandu-le direct. In cazul in care scriptul e intr-un alt director poti asa: import sys sys.path.append("/home/me/mypy") import ......
(Cauta mai multe despre PYTHONPATH)
|
|
« Ultima modificare: Septembrie 04, 2009, 15:46:31 de către Andrei Homorodean »
|
Memorat
|
....staind....
|
|
|
•bogdan2412
|
|
« Răspunde #11 : Septembrie 04, 2009, 17:10:26 » |
|
Vrea sa importe un fisier cu nume dinamic si asta e mai greu . Adica daca are variabila nume-concurs = "bla", vrea sa importe bla.bla-config. Nu stiu o metoda eleganta de a face asta Poti sa faci ceva de genu exec("import %s.%s-config" % (nume_concurs, nume_concurs))
exec executa stringul dat ca parametru, dar nu prea cred ca e foarte sigur sa faci asta Later edit: Se pare ca exista functia __import__ pentru asta: http://docs.python.org/library/functions.html#__import__
|
|
« Ultima modificare: Septembrie 04, 2009, 17:25:30 de către Bogdan Tataroiu »
|
Memorat
|
|
|
|
•toni2007
|
|
« Răspunde #12 : Septembrie 04, 2009, 21:20:32 » |
|
Asta imi trebuia. Mersi .
|
|
|
Memorat
|
|
|
|
•sandyxp
Strain
Karma: -1
Deconectat
Mesaje: 39
|
|
« Răspunde #13 : Septembrie 04, 2009, 22:46:47 » |
|
Dar nu merge chiar asa, import dirA.dirB.fisier (pentru dirA/dirB/fisier.py). Eu zic ca ai cam 3 posibilitati: - Incarci configul cu import, calea fiind relativa la directorul curent. Dar nu e o cale normala, pentru ca directoarele insiruite cand servesti calea sunt de fapt pachete python, deci de ex daca faci import contest.round_name.round_name_config ca sa importi contest/round_name/round_name_config.py, trebuie ca `contest` si `contest/round_name` sa fie pachete (adica fiecare director sa contina cate un __init__.py gol in el).
Apropo, daca faci asa sau ca la metoda 2, nu poti avea round_name-config pt ca liniuta nu e admisa intr-un nume de variabila. (si instructiunea ar importa exact acel nume ca variabila).
- Ca la metoda 1, numai ca in loc ca directorul `contest` sa fie pachet, il adaugi la calea de importare a lui python. Dar il adaugi pe primul loc, ca nu cumva sa existe alt pachet cu numele rundei prin librariile standard.
Exemplu: import sys sys.path.insert(0, 'contest') import test.test_config as config_runda # pt runda test del sys.path[0] # takes O(1) time # in pachet se vor afla variabilele rundei print config_runda.studs print config_runda.probs
- Sa incarci efectiv textul fisierului de configurare intr-o variabila, sa-l compilezi cu functia builtin compile, si apoi sa il executi cu keywordul `exec` (preferabil in cadrul unei clase, in constructor, dar in orice caz, apoi trebuie sa convertesti din variabilele locale definite in fisierul ala de config in variabile membre ale clasei, pt a putea fi accesate ulterior). Un cod care ar face asta (da, m-am chinuit degeaba la asta ):
class Round:
__params__ = ['problems', 'students']
def __validate_param(self, x): return x[0] in self.__params__
def __init__(self, name): config_file = 'contest/%s/%s_config.py' % (name, name) exec compile(open(config_file).read(), '/dev/null', 'exec')
self.__dict__.update( filter(self.__validate_param, locals().items()) )
Eu de ex am ales sa folosesc metoda 2, dar in loc sa folosesc un fisier de configurare, daca tot am facut din directorul rundei un pachet, am mutat codul de configurare in __init__.py (de ex pt runda test, in contest/test/__init__.py) si asa poti face direct import test si cu asta basta
|
|
|
Memorat
|
|
|
|
|