importing a class from another python file issue - python

Hi I want to import a class from another file in python, everything works however the class I want to import receives a command line argument. After I import (which is successful) how would I supply that command line argument in the class? (side:note is this a superclass or something? idk what that means)
#class I'm importing
class trend:
def __init__(self):
self.user_name = sys.argv[1] #receives commandline argument
_______________________________________________________________
#class I want to use it in
class game:
def __init__(self):
self.twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
def do_something(self):
import filenameforthetrendclass as TC
game = TC.trend() #how do I bring in the commandline argument in here?

It's a bad idea to use sys.argv anywhere but at the top-level (main, if you have one). That's something you should pass in.
First, re-write Trend to take user_name as a parameter to its constructor.
Quick example with just Trend:
class Trend(object):
def __init__(self, user_name):
self.user_name = user_name
trend = Trend(sys.argv[1])
Now integrating the whole concept:
import sys
from filenameforthetrendclass import Trend
class Game(object):
def __init__(self):
self.twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
def do_something(self, user_name):
a_trend = Trend(user_name) # was originally 'game = '
def main():
game = Game()
game.do_something(sys.argv[1])
Notes:
I'm using uppercase names for classes
I'm definitely not having a class named game and then using game as a local variable somewhere.

Related

How to import instances of a Class in Python?

class Tweeter:
def __init__(self, api_key, api_secret_key, bearer_token, access_token, access_token_secret ):
self.api_key = api_key
self.api_secret_key = api_secret_key
self.bearer_token = bearer_token
self.access_token = access_token
self.access_token_secret = access_token_secret
auth = tweepy.OAuthHandler(self.api_key, self.api_secret_key)
auth.set_access_token(self.access_token, self.access_token_secret)
self.api = tweepy.API(auth)
How can I import an instance of a class from the file in which the instance was created to another .py file.
For example: instance1 = Tweeter(xargument,yargument, zargument)
How do import and/or call the instance that I created in another file without having to import the detail that clutter up the code.
Ideally, you'd use parameters to pass around your API client instance, rather than global application imports
You shouldn't need multiple (numbered) instances of it, either.
from classes import Tweeter # for example
if __name__ == "__main__":
t = Tweeter(...)
some_function(t, some, other, args)
from name_of_your_file_that_Tweeter_is_in import Tweeter
from file_x import Tweeter
instance1 = Tweeter(xargument,yargument, zargument)
As long as you initialize your class instance of Tweeter outside of a function or method, then you should be able to import that instance. Keep in mind that all the code that is not within a function or class is ran whenever you import from that file. For example:
# tweeter.py
Class Tweeter:
...
# This code is ran whenever this file is imported from another file
tweeter = Tweeter(<arguments to pass to the __init__ function>)
# my_file.py
from .tweeter import tweeter # Assuming both files are in the same directory
# now you have the same class instance from the tweeter.py file
print(tweeter)

Using Python Click within a class

I've got an old flashcards app that I made that I've repurposed for some aws cert study. I wrote this years ago and overhauled that code, and one of those changes involved using click over argparse, but I'm having some issues using click. My code is below (minus a couple of extra functions):
The idea is that load_deck() needs to read the file argument. The way that I was trying to do it is pass load_deck() the file argument through main()
Finally, running this code states that within the Flashcards().main() call, main() is missing a positional argument self. I think this is a problem with the way I'm using click.
import os
import random
import sys
import click
import keyboard
import ruamel.yaml
class Flashcards:
"""
pass
"""
def __init__(self):
self.deck = ruamel.yaml.YAML()
self.card = ['key', 'value']
def load_deck(self, file):
"""
pass
"""
with open(file, mode='r') as deck:
self.deck = self.deck.load(deck)
#click.command()
#click.option('-f', '--file', default='aws.yaml', help='specifies yaml file to use')
#click.option('-r', '--reverse', default=False, help='displays values prompting user to guess keys')
def main(self, file, reverse):
"""
pass
"""
self.load_deck(file)
if reverse is True:
self.deck = [
[card[1], card[0]
] for card in self.deck]
os.system('clear')
print('Press [SPACEBAR] to advance. Exit at anytime with [CTRL] + [C]\n'
'There are {} cards in your deck.\n'.format(len(self.deck)))
try:
while True:
self.read_card()
self.flip_card()
except KeyboardInterrupt:
# removes '^C' from terminal output
os.system('clear')
sys.exit(0)
if __name__ == "__main__":
Flashcards().main()
The program reads a yaml file in the following format (it was previously a spanish flashcard app):
bajar: to descend
borrar: to erase
contestar: to answer
Click isn't naturally designed to work this way, see for example this issue which also includes some workarounds by folks in the comments if you want to go that route.
In your case, you could just yoink main out of the class and have it instantiate Flashcards for you:
#click.etc.
def main(file, reverse):
f = Flashcards()
f.load_deck(file)
# And so on, using 'f' instead of 'self'
I found this workaround:
import click
class Stub:
pass
viking = click.make_pass_decorator(Stub,ensure=True)
#click.group()
#viking
#click.pass_context
def cli(ctx,_):
ctx.obj = Viking()
class Viking(Stub):
def __init__(self):
self.name = "Thor"
#cli.command()
#viking
def plunder(self):
print(f"{self.name} attacks")
#cli.command()
#viking
def sail(self):
print("whoosh")
cli()

Single instance of class from another module

I come from Java background and most of my thinking comes from there. Recently started learning Python. I have a case where I want to just create one connection to Redis and use it everywhere in the project. Here is how my structure and code looks.
module: state.domain_objects.py
class MyRedis():
global redis_instance
def __init__(self):
redis_instance = redis.Redis(host='localhost', port=6379, db=0)
print("Redus instance created", redis_instance)
#staticmethod
def get_instance():
return redis_instance
def save_to_redis(self, key, object_to_cache):
pickleObj = pickle.dumps(object_to_cache)
redis_instance.set(key, pickleObj)
def get_from_redis(self, key):
pickled_obj = redis_instance.get(key)
return pickle.loads(pickled_obj)
class ABC():
....
Now I want to use this from other modules.
module service.some_module.py
from state.domain_objects import MyRedis
from flask import Flask, request
#app.route('/chat/v1/', methods=['GET'])
def chat_service():
userid = request.args.get('id')
message_string = request.args.get('message')
message = Message(message_string, datetime.datetime.now())
r = MyRedis.get_instance()
user = r.get(userid)
if __name__ == '__main__':
global redis_instance
MyRedis()
app.run()
When I start the server, MyRedis() __init__ method gets called and the instance gets created which I have declared as global. Still when the service tries to access it when the service is called, it says NameError: name 'redis_instance' is not defined I am sure this is because I am trying to java-fy the approach but not sure how exactly to achieve it. I read about globals and my understanding of it is, it acts like single variable to the module and thus the way I have tried doing it. Please help me clear my confusion. Thanks!

Python classes: How should a built it

I am trying to create a class called ListenerVilma that has two methods: "Clock_" and "Diagnostics_". Nevertheless both methods will call inner functions. The following code shows my attempt to achieve the mentioned behavior, but when I call ListenerVilma.Clock_() the get the following error:
TypeError: unbound method Clock_() must be called with ListenerVilma instance as first argument (got nothing instead)
How should a create my class ListenerVilma???
Thanks.
#!/usr/bin/env python
import rospy
from rosgraph_msgs.msg import Clock
from diagnostic_msgs.msg import DiagnosticArray
class ListenerVilma:
"""Class that listens all topics of the file vilmafeagri"""
def Clock_(self):
"""Method that listens the topic /clock if the file vilmafeagri"""
def __init__(self):
self.listener()
def callback(self, clock):
print clock
def listener(self):
rospy.Subscriber('clock', Clock, self.callback)
def Diagnostics_(self):
"""Method that listen the topic /diagnostics from rosbag file vilmafeagri"""
def __init__(self):
self.listener()
def callback(self, diagnostics):
print diagnostics
def listener(self):
rospy.Subscriber('diagnostics', DiagnosticArray, self.callback)
if __name__ == '__main__':
rospy.init_node('listener', anonymous=True)
ListenerVilma.Clock_()
rospy.spin()
the error is in line 41 in ListenerVilma.Clock_() here your directly using the method of your class so no implicit argument is pass and a instance of ListenerVilma is expected. The solution is ListenerVilma().Clock_() this first create a instance of your class and from say instance call its Clock_ method.
Outside that, your class construction is very weird, the __init__ is used to initialize a class and a basic class construction is like this
class Foo:
"""example class"""
def __init__(self,*argv,**karg):
"""initialize this class"""
#do something with argv and/or karg according to the needs
#for example this
print "init argv", argv
print "init karg", karg
self.ultimate=42
def do_stuff(self):
"""this method do something"""
print "I am doing some stuff"
print "after 7.5 million years of calculations The Answer to the Ultimate Question of Life, the Universe, and Everything is: ", self.ultimate
def do_some_other_stuff(self,*argv,**karv):
"""this method do something else"""
print "method argv", argv
print "method karg", karg
# basic usage
test = Foo(1,2,3,key_test=23)
test.do_stuff()
test.do_some_other_stuff(7,8,9,something=32)
test.ultimate = 420
test.do_stuff()
I am not quite sure what you intentions are, but you build Clock_ and Diagnostics_ as a class, but they are not, and as right now they do nothing, if you want they to be class on their own do
class Clock_:
def __init__(self):
self.listener()
def callback(self, clock):
print clock
def listener(self):
rospy.Subscriber('clock', Clock, self.callback)
and the same with Diagnostics_, and I don't see a reason to the listener method so I would put what it does in the __init__, but maybe the rospy need it? I don't know, but for the looks of it then it should be used as
rospy.init_node('listener', anonymous=True)
Clock_()
Diagnostics_()
rospy.spin()
The Clock_ method doesn't belong to the class; it's an 'instance' method.
There are two options
In the main function: create an instance of ListenerVilma: listener = ListenerVilma(), or
In the ListenerVilma class: annotate the methods with #classmethod and make the class inherit from object: class ListenerVilma(object):. But remember, the first argument in your methods will be a reference to the class and not a reference to an instance.
The following code performs better the behavior that I wanted. :)
class ListenerVilma:
def CLOCK(self):
def clock_sub():
rospy.Subscriber('clock', Clock, clock_callback)
def clock_callback(clock):
print clock
clock_sub()
def DIAGNOSTICS(self):
def diagnostics_sub():
rospy.Subscriber('diagnostics', DiagnosticArray, diagnostics_callback)
def diagnostics_callback(diagnostics):
print diagnostics
diagnostics_sub()
if __name__ == '__main__':
rospy.init_node('listener', anonymous=True)
myVilma = ListenerVilma()
myVilma.CLOCK()
myVilma.DIAGNOSTICS()
rospy.spin()

Error "listed is not defined" in a Python class

Why do I get the error listed is not defined in the following code snippet?
import socket,select
from threading import *
import time
neighbours=[]
def neighbourfuncall():
print('In neighbours')
class pyserver(Thread):
dictn={}
HOST=socket.gethostname()
PORT=8888
buf=1024
ADDR=(HOST,PORT)
listed=[]
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(ADDR)
sock.listen(30)
def __init__(self):
self.interval=6
listed.append(sock)
thread=threading.Thread(target=neighbourfuncall,args=())
thread.daemon=True
thread.start()
def run(self):
while True:
sel,out,spl=select.select(listed,[],[],15.0)
for s in sel:
if s==sock:
client,address=sock.accept()
listed.append(client)
dest=client.recv(buf)
dictn[client]=dest
else:
pass
serv=pyserver()
serv.run()
You have to access listed with the following syntax:
pyserver.listed = ["I need to study more Python!"]
since it's a static class variable.
As you're in a class, you need to use self.list.append(smth). All class variables must be accessed using self.
By the way, socket operations must be in __init__(). You'd better do this:
def __init__(self):
self.smth=socket()
self.other=[]
self.smth.DoSomething()
def Hello(self):
self.other.append("Hello") #just example

Categories

Resources