n88b
n88b

Reputation: 153

How do I replace variables in python class?

I was instructed to define a class which takes 3 variables: (which looks something like this)

class random(object):
    def __init__(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c
        self.result= #calculations with a,b and c.
    def __str__(self):
        #functions so that self.result prints correctly

However, I also have to write another function in the above class:

    def read(#takes whatever parameter I need)
         #functions which I dont know how to write

This function should allow me to read from another file (lets call it file.txt"), and replace the self.a, self.b and self.c with information from that file, if you know what I mean? like for example:

itemA=random(1,2,3) 

and file.txt contains three lines:

6
7
8

running the following:

itemA.read()

is suppose to replace the 1,2,3 in the parameter as 6,7,8, so that

itemA=random(6,7,8)

How can I achieve that? I already wrote the part that reads and reproduce random(6,7,8),with:

fileHandle=open('file.txt', 'r')
fileHandle.readlines()
#some codes that turn string into integer/floats
fileHandle.close()
random(#put integers in)

however I am not able to update itemA from random(1,2,3) to random(6,7,8) without writing manually:

itemA=itemA.read() #in python shell

btw itemA is just an example name, it can be named anything so I cant actually use itemA in my calculations...

Upvotes: 0

Views: 100

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1123560

Inside a method on your class, you can manipulate attributes by setting them on self, just like you did in the __init__ method.

All you need to do then is set those attributes after reading. You probably want your read() method to take a filename too:

def read(self, filename):
    with open(filename) as fh:
        self.a = int(fh.readline())
        self.b = int(fh.readline())
        self.c = int(fh.readline())
        self.result = # same calculation

So when you call itemA.read() it'll alter the attributes in place; there is no need to return anything here.

You could reuse the __init__ method to set those attributes, and avoid having to duplicatoe the calculation for the self.result attribute:

class random(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
        self.result = #calculations with a,b and c.

    def read(self, filename):
        with open(filename) as fh:
            a = int(fh.readline())
            b = int(fh.readline())
            c = int(fh.readline())
            self.__init__(a, b, c)  # set the attributes plus result

or you could share a separate method between __init__ and read():

class random(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
        self._calculate_result()

    def _calculate_result(self)
        self.result = #calculations with self.a, self.b and self.c.

    def read(self, filename):
        with open(filename) as fh:
            self.a = int(fh.readline())
            self.b = int(fh.readline())
            self.c = int(fh.readline())
            self._calculate_result()  # set the result

It would work something like this:

itemA = random(1, 2, 3)
itemA.read('file.txt')
# now itemA.a is set to 4, itemA.b is set to 5 and item.c is set to 6

It could be that you wanted to produce an instance of the class random either by providing a, b and c directly, or by reading from a file. This is a little more advanced, but that means you are providing two different factory methods, two different ways to produce instances of random. I tend to use class methods to implement extra factory methods:

class random(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
        self.result = #calculations with a,b and c.

    @classmethod
    def from_file(self, filename):
        with open(filename) as fh:
            a = int(fh.readline())
            b = int(fh.readline())
            c = int(fh.readline())
            return cls(a, b, c)  # create a new instance of this class

I renamed the read method to from_file() to document better that this is a factory method. You'd use it like this:

itemA = random(1, 2, 3)
itemB = random.from_file('file.txt')

This creates two separate instances, one with values provided directly, the other by reading from a file.

Upvotes: 2

Related Questions