0

I need to return the output from multiple functions inside a class in a dictionary format

I have tried using Python.

dict={}
class Compute():

    def vm(self):
        for obj in data['profile']:
            for region_name in obj['region']:
                conn = boto3.resource('ec2', aws_access_key_id=obj["access_key"], aws_secret_access_key=obj["secret_key"],
                    region_name=region_name)
                instances = conn.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running', 'stopped']}])
                for instance in instances:
                    instance_count.append(instance)
                    instanceCount = str(len(instance_count))
        dict['VM'] = len(instance_count)


    #Subnet
    def subnet(self):
        subnet_count=0
        for obj in data['profile']:
            for region_name in obj['region']:
                conn = boto3.client('ec2', aws_access_key_id=obj["access_key"], aws_secret_access_key=obj["secret_key"],
                                  region_name=region_name)
                subnet = conn.describe_subnets()
                #print('subnet'+ ' '+ region_name + ' ' +str(len(subnet['Subnets'])))
                subSize = len(subnet['Subnets'])
                subnet_count+=subSize
        dict['Networks'] = subnet_count

    #VPCS
    def vpc(self):
            for obj in data['profile']:
                for region_name in obj['region']:
                    conn = boto3.resource('ec2', aws_access_key_id=obj["access_key"], aws_secret_access_key=obj["secret_key"],
                      region_name=region_name)
                    vpcs = conn.vpcs.filter()
                    for vpc in vpcs:
                        vpc_count.append(vpc)
                        vpcCount = str(len(vpc_count))

            dict['VPCs'] = len(vpc_count)

     print(dict)    #this only prints {}   


    def runcompute(self):
        if __name__ == '__main__':
            Thread(target=self.vm).start()
            Thread(target=self.subnet).start()
        Thread(target=self.vpc).start()

if __name__ == '__main__':
    try:
        if sys.argv[1]=='compute':
             run = Compute()
             run.runcompute()

"Now How to print the results in json/ dict format in the console. I expect out put in {"VM": 45, "VPCs": 23, "Networks": 35} format But it print {} but that is wrong."

1
  • 1
    dict only exists within the methods of your class. This is not the same dict inside vm() and the one declared at the top. Also you should really consider not using dict as a variable name since it's a python Keyword. Commented Oct 23, 2019 at 8:04

1 Answer 1

1

For what I understood you need to actually define a constructor for your class. Since it seems to be a simple dictionary we can inherit directly.

class Compute(dict):
     def __init__(self): 
         super().__init__(self) 

     def my_method(self): # equivalent of your methods in your class
         self["foo"] = 1

So when I do

run = Compute()
print(run)
>> {} # we just created the object

And when I call the methods

run.my_method()
print(run)
>> { 'foo': 1 }  # and here we are

A complete simple example:

import sys
from threading import Thread

class Compute(dict):
    def __init__(self):
        super().__init__(self)  # short version
        # super(Compute, self).__init__(self)  # long version

    def _vm(self):
        instance_count = [0] * 45  # do your stuff
        self["VM"] = len(instance_count)

    def _subnet(self):
        subnet_count = 35  # do your stuff
        self["Networks"] = subnet_count

    def _vpc(self):
        vpc_count = [0] * 23  # do your stuff
        self["VPCs"] = len(vpc_count)

    def runcompute(self):
        # Create the threads
        vm = Thread(target=self._vm)
        subnet = Thread(target=self._subnet)
        vpc = Thread(target=self._vpc)
        # Actually start the threads
        vm.start()
        subnet.start()
        vpc.start()

        print(self)  # If you really want to print the result here

if __name__ == "__main__":
    if sys.argv[1] == "compute":
        run = Compute()
        run.runcompute()

Notice that I added the _ in front of _vm, _subnet and _vpc. This is mostly a naming convention (read more here and here) used to declare something "private". Since you only want to use those methods through runcompute() it fits the usage perfectly.

Sign up to request clarification or add additional context in comments.

6 Comments

I am using python 3.7.2. it is not supporting super without arguments. And Also My Task is if I run Class all methods should be called and it should show all the output of functions.
class Compute(dict): TypeError: dict expected at most 1 arguments, got 3
super should work just fine, I'm using Python3.6.8 and I just checked the doc for the 3.7 and there's nothing changed. You can try the long version: super(Compute, self).__init__(self).
What do you mean when you "run Class", do you mean you want to assign all the values VM, Networks and VPCs when doing run = Compute() ?
Okay, I think I got what you mean, when instantiating your class you want to automatically create the dictionary (by using your 3 methods vm, subnet and vpc) and each of those method should be run on different threads. Right ? Or do you want to have to run run.runcompute() to actually fill the dict ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.