Pagini: [1]   În jos
  Imprimă  
Ajutor Subiect: Cum declari o clasa in python ?  (Citit de 3506 ori)
0 Utilizatori şi 1 Vizitator pe acest subiect.
toni2007
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« : 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 :
Cod:

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
Nu mai tace
*****

Karma: 219
Deconectat Deconectat

Mesaje: 596



Vezi Profilul
« 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
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« 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++ :

Cod:
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
Nu mai tace
*****

Karma: 219
Deconectat Deconectat

Mesaje: 596



Vezi Profilul
« 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
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« Răspunde #4 : August 11, 2009, 21:42:47 »

Cam asta imi trebuia, dar daca nu merge o sa incerc altfel.
Memorat
bogdan2412
Echipa infoarena
Nu mai tace
*****

Karma: 410
Deconectat Deconectat

Mesaje: 951



Vezi Profilul
« 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
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« Răspunde #6 : August 13, 2009, 21:50:03 »

Da, pentru Django aveam nevoie, imi merge. Mersi mult Very Happy.
Memorat
sandyxp
Strain
*

Karma: -1
Deconectat Deconectat

Mesaje: 39



Vezi Profilul
« 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
Cod:
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
Echipa infoarena
Nu mai tace
*****

Karma: 410
Deconectat Deconectat

Mesaje: 951



Vezi Profilul
« Răspunde #8 : Septembrie 02, 2009, 18:23:54 »

Exemplu din C e diferit de ce vroia sa faca in python. Smile 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 Smile
Exemplu din C intr-adevar se implementeaza cum ai zis tu.
Memorat
toni2007
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« 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
Nu mai tace
*****

Karma: 10
Deconectat Deconectat

Mesaje: 296



Vezi Profilul
« 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
Cod:
from configx import *

si poti accesa clasele si variabilele specificandu-le direct.

In cazul in care scriptul e intr-un alt director poti asa:

Cod:
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
Echipa infoarena
Nu mai tace
*****

Karma: 410
Deconectat Deconectat

Mesaje: 951



Vezi Profilul
« Răspunde #11 : Septembrie 04, 2009, 17:10:26 »

Vrea sa importe un fisier cu nume dinamic si asta e mai greu Smile . Adica daca are variabila nume-concurs = "bla", vrea sa importe bla.bla-config.

Nu stiu o metoda eleganta de a face asta Smile Poti sa faci ceva de genu
Cod:
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 Smile

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
Nu mai tace
*****

Karma: 160
Deconectat Deconectat

Mesaje: 663



Vezi Profilul
« Răspunde #12 : Septembrie 04, 2009, 21:20:32 »

Asta imi trebuia. Mersi Very Happy.
Memorat
sandyxp
Strain
*

Karma: -1
Deconectat Deconectat

Mesaje: 39



Vezi Profilul
« 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  Tongue ):
    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 Smile
Memorat
Pagini: [1]   În sus
  Imprimă  
 
Schimbă forumul:  

Powered by SMF 1.1.19 | SMF © 2006-2013, Simple Machines