Kalanamith
Kalanamith

Reputation: 20648

Python how to create a new Object with new instance values

I have created a python script to generate random numbers and store them in a list but once i ran the script um getting same values

stat_lst = []
class Sample_stats:
    ts = datetime.now()
    total = randint(10,10000)
    seed = randint(5,5000)
    post_id = randint(0,100)
    site_id = 1
    twitter = randint(5,5000)
    facebook = randint(5,5000)
    gplus = randint(5,5000)
    pinterest = randint(5,5000)
    clicks = randint(5,5000)
    subpage_id = 1
    mouse_overs = randint(5,5000)
    impressions = randint(5,5000)


for num in range(0,20):
    x = Sample_stats()
    stat_lst.append(x)

Output

for item in stat_lst:
    print item.total

um getting the same value here can anyone tell me how to generate random data from here?

Upvotes: 0

Views: 118

Answers (2)

That1Guy
That1Guy

Reputation: 7233

While @Martijn Pieters is completely correct, I think further explanation is needed to understand why this happened.

Everything in Python is an object. The class itself, even before instantiation is an object in that it is an instance of its own metaclass, and that metaclass is only instantiated at class definition time.

For example:

def myfunc():
    print 'inside myfunc'
    return 'mystring'

class MyClass:
    myattr = myfunc()

When we execute this code (before instantiating the class) we see:

>>>inside myfunc

If we extend the code:

my_obj = A()
new_objc = A()

We do not see any output.

This is because when Python see's the class definition, it instantiates the class's metaclass. At this point, all class attributes are set on the class object. When instantiating the class A.myattris not redefined.

Because of this, your code produces a list of instances with the same attributes.

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1121366

You assigned the values to class attributes, which are calculated only once when the class itself is defined. These attributes are not (re)calculated when you create instances.

Move the randint() calls to an __init__ method instead:

class Sample_stats:
    def __init__(self):
        self.ts = datetime.now()
        self.total = randint(10,10000)
        self.seed = randint(5,5000)
        self.post_id = randint(0,100)
        self.site_id = 1
        self.twitter = randint(5,5000)
        self.facebook = randint(5,5000)
        self.gplus = randint(5,5000)
        self.pinterest = randint(5,5000)
        self.clicks = randint(5,5000)
        self.subpage_id = 1
        self.mouse_overs = randint(5,5000)
        self.impressions = randint(5,5000)

Now each attribute is set on the instance instead, when you create it with Sample_stats().

Upvotes: 6

Related Questions