What you want isn't directly possible in JSON, because it doesn't support "templating".
One solution would be to use a templating language such as Jinja to write a JSON template, then load this file without the json library and fill in the values using Jinja, and finally use json.loads to load a dictionary from your rendered string.
Your json-like file could look something like this:
Copy{"path_to_folder": "/Users/{{ user_name }}/my_folder/"}
Your Python code:
Copyimport json
from jinja2 import Environment, FileSystemLoader
env = Environment(
FileSystemLoader("path/to/template")
)
template = env.get_template("template_filename.json")
def print_json(username):
return json.loads(
template.render(user_name=username)
)
...
In fact, if this is a simple one-time thing, it might even be better to use Python's built-in templating. I would recommend old-style formatting in the case of JSON, because otherwise you'll have to escape a lot of braces:
JSON file:
Copy{"path_to_folder": "/Users/%(user_name)s/my_folder/"}
"Rendering":
Copywith open("path/to/json") as f:
rendered = json.loads(f.read() % {"user_name": username})
Answer from L3viathan on Stack Overflowarrays - sending json object to function python - Stack Overflow
python - what does it mean by 'passed by assignment'? - Stack Overflow
How to use a json object as parameters to a python function.
How to assign variables using JSON data in python - Stack Overflow
tl;dr: You're right that Python's semantics are essentially Java's semantics, without any primitive types.
"Passed by assignment" is actually making a different distinction than the one you're asking about.1 The idea is that argument passing to functions (and other callables) works exactly the same way assignment works.
Consider:
def f(x):
pass
a = 3
b = a
f(a)
b = a means that the target b, in this case a name in the global namespace, becomes a reference to whatever value a references.
f(a) means that the target x, in this case a name in the local namespace of the frame built to execute f, becomes a reference to whatever value a references.
The semantics are identical. Whenever a value gets assigned to a target (which isn't always a simple name—e.g., think lst[0] = a or spam.eggs = a), it follows the same set of assignment rules—whether it's an assignment statement, a function call, an as clause, or a loop iteration variable, there's just one set of rules.
But overall, your intuitive idea that Python is like Java but with only reference types is accurate: You always "pass a reference by value".
Arguing over whether that counts as "pass by reference" or "pass by value" is pointless. Trying to come up with a new unambiguous name for it that nobody will argue about is even more pointless. Liskov invented the term "call by object" three decades ago, and if that never caught on, anything someone comes up with today isn't likely to do any better.
You understand the actual semantics, and that's what matters.
And yes, this means there is no copying. In Java, only primitive values are copied, and Python doesn't have primitive values, so nothing is copied.
the only difference is that 'primitive types'(for example, numbers) are not copied, but simply taken as objects
It's much better to see this as "the only difference is that there are no 'primitive types' (not even simple numbers)", just as you said at the start.
It's also worth asking why Python has no primitive types—or why Java does.2
Making everything "boxed" can be very slow. Adding 2 + 3 in Python means dereferencing the 2 and 3 objects, getting the native values out of them, adding them together, and wrapping the result up in a new 5 object (or looking it up in a table because you already have an existing 5 object). That's a lot more work than just adding two ints.3
While a good JIT like Hotspot—or like PyPy for Python—can often automatically do those optimizations, sometimes "often" isn't good enough. That's why Java has native types: to let you manually optimize things in those cases.
Python, instead, relies on third-party libraries like Numpy, which let you pay the boxing costs just once for a whole array, instead of once per element. Which keeps the language simpler, but at the cost of needing Numpy.4
1. As far as I know, "passed by assignment" appears a couple times in the FAQs, but is not actually used in the reference docs or glossary. The reference docs already lean toward intuitive over rigorous, but the FAQ, like the tutorial, goes much further in that direction. So, asking what a term in the FAQ means, beyond the intuitive idea it's trying to get across, may not be a meaningful question in the first place.
2. I'm going to ignore the issue of Java's lack of operator overloading here. There's no reason they couldn't include special language rules for a handful of core classes, even if they didn't let you do the same thing with your own classes—e.g., Go does exactly that for things like range, and people rarely complain.
3. … or even than looping over two arrays of 30-bit digits, which is what Python actually does. The cost of working on unlimited-size "bigints" is tiny compared to the cost of boxing, so Python just always pays that extra, barely-noticeable cost. Python 2 did, like Java, have separate fixed and bigint types, but a couple decades of experience showed that it wasn't getting any performance benefits out of the extra complexity.
4. The implementation of Numpy is of course far from simple. But using it is pretty simple, and a lot more people need to use Numpy than need to write Numpy, so that turns out to be a pretty decent tradeoff.
Similar to passing reference types by value in C#.
Docs: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-reference-type-parameters#passing-reference-types-by-value
Code demo:
# mutable object
l = [9, 8, 7]
def createNewList(l1: list):
# l1+[0] will create a new list object, the reference address of the local variable l1 is changed without affecting the variable l
l1 = l1+[0]
def changeList(l1: list):
# Add an element to the end of the list, because l1 and l refer to the same object, so l will also change
l1.append(0)
print(l)
createNewList(l)
print(l)
changeList(l)
print(l)
# immutable object
num = 9
def changeValue(val: int):
# int is an immutable type, and changing the val makes the val point to the new object 8,
# it's not change the num value
val = 8
print(num)
changeValue(num)
print(num)
Hi there, I'm learning python and I don't know how to do the following, or even if it's possible.I have a json object obj = { 'one': 1, 'two': 2 }, and a python function f(). The goal is to have the json object used as the parameters for the function, like this: f(one=1, two=2).For this example that's fine, but the problem is that the json keys are not always the same, and if my json object is obj={'cat': 'purr', 'dog': 'bark'}, the function would be called with f(cat='purr', dog='bark').If the json obj is {'first', '1st', 'second':'2nd', 'third':'3rd'}, the function would be called with f(first='1st', second='2nd', third='3rd').
The function is from a library, and for me to rewrite it to accept kwargs would imply overriding all the functions in the library (since i will be using pretty much all the functions from the library).
Is there a way to do this without overriding all the functions from the library?
Thank you in advance.
Your issue is not with loading the json data into products variable. After loading, you are trying to retrieve values from products in an incorrect manner which leads to Key Error. Your products is basically a dictionary of list of dictionary
Here is the correct way to retrieve necessary values from products:
print(products['products'][0]['id'])
#632910392
print(products['products'][0]['title'])
#IPod Nano - 8GB
print(products['products'][0]['variants'][0]['product_id'])
#632910392
Try analysing the deep structure of your products variable so that you can learn to retrieve any value in it by yourself. Cheers!
Consider accessing the array by using products["products"] for instance:
import json
result = json.loads('{"products": [ {"id": "1234", "title": "foo"} ]}')
for it in result["products"]:
print("id: " + it["id"] + " title: " + it["title"])
You have to pass each key as a separate argument (or as a list of separate arguments).
def my_function(obj, *fields):
for f in fields:
try:
obj = obj[f]
except KeyError:
logging.exception("Exceptoin: ")
return
return obj
my_function(my_json, "DataChangedEntry", "CurrentValue", ...)
I confess that this idea of sending this data separately to a function is quite different.
But to directly return the value aaaaaaa:
- Send the first argument as the JSON object value
- Send the second argument as the JSON object name string
- Send third argument as key list
Then you can use eval() to convert the union of strings into code:
def my_function(json_full, json_prefix, json_field):
my_json = json_full
my_json_str = json_prefix
key_field = '["' + '"]["'.join(json_field) + '"]'
try:
value = eval(f'{json_prefix}{key_field}')
return value
except Exception as e:
return e
def main():
my_json = {
"DataChangedEntry": {
"CurrentValue": {
"RefId": {
"Value": "aaaaaaa"
},
},
},
}
get_value = my_function(my_json, 'my_json', ["DataChangedEntry","CurrentValue","RefId","Value"])
print(get_value)
if __name__ == "__main__":
main()
Output:
aaaaaaa
Hello all,
I hope this is the right place to ask this. I am trying to learn Scrapy and I'm currently trying to pass a JSON Object as an argument so that I can get the urls and XPath selectors and also generate the item class dynamically instead of hardcoding them. I wanted to know if there was any way to do so? I can pass a string argument using the -a flag like
scrapy crawl myspider -a start_urls="url.com"
but how can I pass a dict? Should I pass a string containing a dict and then convert it back to a dict in my Python code? Or is there a better way? Thanks for your help!
Trying to understand how Python works passing arguments in functions. I've heard that Python's approach is referred to as "pass by assignment" or "pass by object reference".
How does this differ from the more traditional "pass by reference" approach? Hopefully someone can explain it in a way that's easy to understand.