0

I'd like to know if I can have a parameter list with keywords given inside a string that I can pass into a function? Basically, the parameter list may or may not have keywords, so the parameter list would have variable 'types'. Here's an example of what I'm trying to do:

from bs4 import BeautifulSoup
import urllib.request as urlreq
import my_parameters    # can have variable values

# my_parameters.useful_token_concept = ["h1", "class_ = some_class"]
# I want to pass these above parameters into a function; "class_" is
# a keyword, but it's wrapped in a string => gives me problems

url = my_parameters.url
page = urlreq.urlope(url)
pageHtml = page.read()
page.close()

soup = BeautifulSoup(pageHtml)
# something like the following line works:
# params = soup.find("h1", class_ = "some_class")
params = soup.find(*my_parameters.useful_token_concept)
# params = soup.find(my_parameters.useful_token_concept[0],\
         # my_parameters.useful_token_concept[1])

# I don't know how long the list of attributes/parameter-list to
# BeautifulSoup's find() function will be, nor do I know what keywords,
# if any, will be passed into find(), as given by a user to my_parameters.

print(params) # should print the html the user wants to scrape.

3 Answers 3

2

Why not just use a better representation? I.e, instead of

my_parameters.useful_token_concept = ["h1", "class_ = some_class"]

use

my_parameters.useful_token_concept = ["h1", {"class_": "some_class"}]

Since these values' representation is up to you, using a dict to represent keyword parameters is much simpler than encoding them into a string and then having to parse that string back!

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

Comments

1

You need to split your token list into a dictionary of keyword arguments, and a list of positional arguments.

kwargs = {}
args = []
for i in my_parameters.useful_token_concept:
    bits = i.split('=')
    if len(bits) > 1:
       kwargs[bits[0].strip()] = bits[1].strip()
    else:
       args.append(bits[0].strip())

params = soup.find(*args, **kwargs)

Comments

1

You could create a string representation of how all the arguments would be passed and use eval() to turn them into something you could actually use in a real function call:

my_parameters.useful_token_concept = ["h1", "class_ = some_class"]

def func_proxy(*args, **kwargs):
    " Just return all positional and keyword arguments. "
    return args, kwargs

calling_seq = ', '.join(my_parameters.useful_token_concept)
args, kwargs = eval('func_proxy({})'.format(calling_seq))
print('args:', args)     # -> args: (<Header1 object>,)
print('kwargs:', kwargs) # -> kwargs: {'class_': <class '__main__.some_class'>}

parms = soup.find(*args, **kwargs)

Comments

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.