Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: Python object orientatie en instances  (gelezen 1373 keer)

Offline MKe

  • Lid
Python object orientatie en instances
« Gepost op: 2012/08/20, 09:06:43 »
Hoi,

Ik heb een vrij basic vraagje over OOP in python. Hoe kan ik de data tussen verschillende instanties scheiden zonder dat expliciet in de init te doen? (Is het uberhaupt mogelijk)?

stel, ik heb een class:
class test(object):
    data=[]
    def __init__(self):
        object.__init__(self)
    def add_value(self,value):
        self.data.append(value)
Ik had gedacht dat het 'self' in de add_value methode de actie zou beperken tot de betreffende instantie, maar dat werkt blijkbaar niet zo? Alles wat ik met methode 'add_value' toevoeg werkt meteen door naar latere instanties:
>>> a=test()
>>> a.data
[]
>>> a.add_value('a')
>>> a.data
['a']
>>> b=test()
>>> b.data
['a']
Ik snap dat ik dit kan oplossen door data in de __init__ aan te maken, maar eigelijk wil ik dat niet. Ik wil inheritance gebruiken en het maken van een nieuwe class zo simpel mogelijk maken zonder het gedoe van een __init__ aan te maken aangezien het moet gaan werken als een soort config file.
« Laatst bewerkt op: 2012/08/20, 12:49:20 door MKe »
Mijn blokkendoos blog: http://mke21.wordpress.com/

Re: Python object orientatie en instances
« Reactie #1 Gepost op: 2012/08/20, 10:26:59 »
Edit: vergeet mijn post, had de laatste alinea niet goed gelezen blijkbaar...

Er is een verschil tussen een class variable en instance variable. Een class variable word gedeeld tussen alle instanties van die klasse, zoals in uw voorbeeld.

Probeer eens volgende methode:
>>> class Test(object):
...     def __init__(self):
...         self.data = []
...     def add_value(self, value):
...         self.data.append(value)
...
>>> t1 = Test()
>>> t1.data
[]
>>> t1.add_value('a')
>>> t1.data
['a']
>>> t2 = Test()
>>> t2.data
[]
>>>

Het is trouwens niet nodig om object te initialiseren, gewoon subclassen is voldoende.
« Laatst bewerkt op: 2012/08/20, 10:28:48 door Nunslaughter »

Offline MKe

  • Lid
Re: Python object orientatie en instances
« Reactie #2 Gepost op: 2012/08/20, 12:56:39 »
@Nunslaughter, toch bedankt, maar zoals je zelf al opgemerkt hebt was dit net wat ik niet wil doen. Op dit moment doe ik dat dan maar wel want dat is het enige wat ik zo snel kan bedenken dat werkt.

Even voor de duidelijkheid, ik wil in de config file dingen kunnen maken als:
class subtest1(Test):
    data = ['a','b']

class subtest2(Test):
    data=['c',]

etc....
In plaats van:
class subtest1(Test):
    def __init__(self):
        Test.__init__(self)
        self.data =['a','b']

class subtest2(Test):
    def __init__(self):
        Test.__init__(self)
        self.data =['c',]
Ik wil de gebruiker zo min mogelijk het idee geven dat hij in Python aan het programmeren is.

Re: Python object orientatie en instances
« Reactie #3 Gepost op: 2012/08/20, 15:46:33 »
Ik zou config-files niet in een programmeertaal doen (tenzij misschien een syntactisch zeer simpele taal zoals Lisp of Lua) -- gebruik in plaats daarvan een taal die specifiek dient voor het eenvoudig inlezen van data. Het rechtstreeks inlezen en uitvoeren brengt ook nog een beveiligingsrisico met zich mee, aangezien iedereen commando's zo maar kan uitvoeren. Python is bovendien ook nogal moeilijk om te parsen, wat het inlezen van configuraties traag zou maken.

Voorbeelden zijn XML (nogal "zwaar"), INI-files (eenvoudig maar beperkt), en YAML (eenvoudig en uitgebreid). Kijk eens een keertje of er een eenvoudige YAML-parser voor Python bestaat (vast wel, je kan bijna alles voor Python vinden). Er zijn nog andere opties ook, google eens op de zoekterm "serialization" -- het hangt er maar van af hoe uitgebreid je config-files zijn en hoe gemakkelijk te editten ze moeten zijn.

EDIT: kijk eens naar PyYAML, dat ziet er erg simpel uit.
« Laatst bewerkt op: 2012/08/20, 15:49:00 door SeySayux »
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net

Offline commandoline

  • LoCo-contact
    • marten-de-vries
    • Marten-de-Vries.nl
Re: Python object orientatie en instances
« Reactie #4 Gepost op: 2012/08/21, 17:42:00 »
Je zou nog zoiets kunnen doen:
class Test(object):
    def __init__(self, data):
        self.data = data

   def add_value(...


#de eigenlijke 'files'
Test([1, 2])

Maar ik ben het eens met SeySayux: gebruik Python classes niet als config files.  Er zitten ook genoeg oplossingen voor config files ingebouwd in Python: ConfigParser en json

Offline MKe

  • Lid
Re: Python object orientatie en instances
« Reactie #5 Gepost op: 2012/08/22, 00:03:58 »
Point taken, maar voor mij is het wel logisch om een soort config file te maken in python vanwege de flexibiliteit die dit geeft (misschien is confiGfile niet helemaal het goede woord). Gevorderde gebruikers kunnen hiermee logica (voorwaarden of zelfs simpele functIes) toevoegen aan de 'configfile' terwijl minder gevorderde gebruikers toch nog op een simpele manier simpele configuraties kan maken.  Het komt best veel voor. Zo maak ik als bioinformaticus gebruik van het perl pakket gbrowse, waarbij je in de config ook perlstatements kunt doen. Django is ook een duidelijk voorbeeld waarbij de settings een python modules is (settings.py).  In dit geval is het een script dat een extern programma met zoekalgoritme gebruik, deze uitkomst vervolgens parsed en daar weer een bewrking op doet. Voor het externe programma zijn er vele mogelijkheden, alle met hun eigen bediening. De configfile kan door mij gebruikt worden om  per programma de i/o in te stellen zonder diep in de code te gaan (subclassen van een standaard class) en het geeft ook toekomstige gebruikers de mogelijkheid om nieuwe methoden toe te voegen zonder kennis van de werking van het hele pakket of zelfs van python.

Misschien allemaal een beetje kriptisch, maar hopelijk enigszins duidelijk.

Ondertussen heb ik nu in de man pagina van de tool maar geschreven dat de configuratie m.b.v. Een sub __init__ gedan moet worden. Het werkt tenminste.

Offline commandoline

  • LoCo-contact
    • marten-de-vries
    • Marten-de-Vries.nl
Re: Python object orientatie en instances
« Reactie #6 Gepost op: 2012/08/22, 10:15:54 »
De flexibiliteit van een programmeertaal kan idd voordelen bieden, maar dan zie ik eerlijk gezegd niet in waarom je een class-constructie gebruikt. Je bent dan immers gebonden aan de beperkingen van de syntax van classes, en die bevalt je blijkbaar niet. Voor configuratie-achtige dingen zijn dictionaries ({}) lijkt me beter geschikt. Die kan je ook nog aan 'inheritance' laten doen d.m.v. de dict.update(andere dict) method. Ik weet dat het niet helemaal hetzelfde is, maar misschien voldoet dat ook aan de eisen?

Offline MKe

  • Lid
Re: Python object orientatie en instances
« Reactie #7 Gepost op: 2012/08/22, 15:07:47 »
Dat is idd de overweging. Voor mij is het voordeel van classes dat je gemakkelijk een functies kunt toevoegen aan de data (de class en data is natuurlijk een stuk ingewikkelder dan mijn voorbeeld) en daarom koos ik hiervoor. Nu blijk ik tegen problemen op te lopen, dus moet ik misschien mijn ideeen heroverwegen. Betekent wel weer meer werk, dus voorlopig ga ik maar door met de huidige situatie voor een snel resultaat.

Re: Python object orientatie en instances
« Reactie #8 Gepost op: 2012/08/22, 19:13:41 »
Ik snap het niet 100% wat ge wilt bereiken, maar een class is behoorlijk aan te passen naar eigen wensen. Kijk eens naar de __new__ method en natuurlijk het zelf beheren van __{g|s}etitem__, __setattr__,  __getattribute__ en eventueel __dict__ om  waarden op te slaan.

Voor een project heb ik ook een subclass van dict gemaakt en de __getattr__ en __setattr__ methods aaangepast om dynamische aangemaakte waardes op te slaan.

Offline _Walter_

  • Lid
Re: Python object orientatie en instances
« Reactie #9 Gepost op: 2012/08/27, 23:23:55 »
Op deze manier is het mogelijk, denk ik:

script:
#! /usr/bin/env python

import ConfigParser

config = ConfigParser.ConfigParser()
config.read('test.cfg')

class test():
def __init__(self,beginwaarde):
self.data = []
self.data = self.data + beginwaarde.split(',')
def add_value(self,waarde):
self.data.append(waarde)

# ik zou hier een dictionary aanmaken ipv vars gebruiken.
for item in config.sections():
naam = config.items('sectie1')
for naam,waarde in naam:
vars()[naam] = test(waarde)
print vars()[naam].data
vars()[naam].add_value('e')
print vars()[naam].data

test.cfg:
[sectie1]
eerste = a,b
tweede = c

output:
['a', 'b']
['a', 'b', 'e']
['c']
['c', 'e']


Of sla ik nu de plank mis?

Groet,
Walter