Search code examples
pythonpraw

Python Praw ways to store data for calling later?


Is a dictionary the correct way to be doing this? Ideally this will be more then 5+ deep. Sorry my only language experience is powershell there I would just make an array of object. Im not looking for someone to write the code I just wanna know if there is a better way?

Thanks Cody

My Powershell way:

[$title1,$title2,$title3]

$titleX.comment = "comment here"
$titleX.comment.author = "bob"
$titleX.comment.author.karma = "200"
$titleX.comment.reply = "Hey Bob love your comment." 
$titleX.comment.reply.author = "Alex"
$titleX.comment.reply.reply = "I disagree"

#

Python code Borken:

import praw


d = {}



reddit = praw.Reddit(client_id='XXXX',
                     client_secret='XXXX',
                     user_agent='android:com.example.myredditapp:'
                     'v1.2.3 (by /u/XXX)')

for submission in reddit.subreddit('redditdev').hot(limit=2):
     d[submission.id] = {}
     d[submission.id]['comment'] = {}
     d[submission.id]['title']= {}
     d[submission.id]['comment']['author']={}
     d[submission.id]['title'] = submission.title
     mySubmission = reddit.submission(id=submission.id)
     mySubmission.comments.replace_more(limit=0)
     for comment in mySubmission.comments.list():
        d[submission.id]['comment'] = comment.body
        d[submission.id]['comment']['author'] = comment.author.name

print(submission.title)
print(comment.body)
print(comment.author.name)
print(d)

  File "C:/git/tensorflow/Reddit/pull.py", line 23, in <module>
    d[submission.id]['comment']['author'] = comment.author.name

TypeError: 'str' object does not support item assignment

#

{'6xg24v': {'comment': 'Locking this version.  Please comment on the [original post](https://www.reddit.com/r/changelog/comments/6xfyfg/an_update_on_the_state_of_the_redditreddit_and/)!', 'title': 'An update on the state of the reddit/reddit and reddit/reddit-mobile repositories'}}

Solution

  • I think your approach using a dictionary is okay, but you might also solve this by using a data structure for your posts: Instead of writing

    d[submission.id] = {}
    d[submission.id]['comment'] = {}
    d[submission.id]['title']= {}
    d[submission.id]['comment']['author']={}
    d[submission.id]['title'] = submission.title
    

    you could create a class Submission like this:

    class Submission(object):
        def __init__(self, id, author, title, content):
            self.id = id
            self.author = author
            self.title = title
            self.content = content
            self.subSubmissions = {}
    
        def addSubSubmission(self,submission):
            self.subSubmission[submission,id] = submission
        def getSubSubmission(self,id):
            return self.subSubmission[id]
    

    by using you could change your code to this

    submissions = {}
    for sm in reddit.subreddit('redditdev').hot(limit=2):
        submissions[sm.id] = Submission(sm.id, sm.author, sm.title, sm.content)
    
        # I am not quite sure what these lines are supposed to do, so you might be able to improve these, too
        mySubmission = reddit.submission(id=sm.id)
        mySubmission.comments.replace_more(limit=0)
        for cmt in mySubmission.comments.list():
            submissions[sm.id].addSubSubmission(Submission(cmt.id, cmt.title, cmt.author, cmt.body))
    

    By using this apporach you are also able to export the code to readout the comments/subSubmissions into an extra function which can call itself recursively, so that you can read infitive depths of the comments.