My code keeps giving me the above syntax warning. My code includes, but is not limited to:
class SocketHandler(WebSocketHandler):
def on_message(self, message):
ball = json.loads(message)
user = User(ball['identifier'])
if ball['command'] == 'search':
global our_mongo
search_results = our_mongo.find({'$text':{'$search':ball['search_term']}},{'score':{'$meta':"textScore"}})
self.write_message({
'command': 'search-results',
'results': list(search_results.sort([('score', {'$meta': 'textScore'})]).limit(10)),
})
elif ball['command'] == 'save-node': # hopefully this can handle both new nodes and changes to nodes
node_dict = ball['node_dict']
if 'importance' in node_dict.keys():
node_dict['importance'] = int(node_dict['importance'])
try:
node_obj = node.create_appropriate_node(node_dict)
print('node made. looks like: '+str(node_obj)+'. Now time to put it into the DB...')
global our_mongo
# take a look at the dependencies now
previous_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find({"_id": node_obj.id}))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
print('prev deps are: '+str(previous_dependency_ids))
our_mongo.upsert({ "_id": node_obj.id }, node_obj.__dict__)
# take a look at the current dependencies
current_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find({"_id": node_obj.id}))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
print('curr deps are: '+str(current_dependency_ids))
update_our_DAG()
# send an update of the graph to the user if there is a new dependency:
for new_dependency in set(current_dependency_ids) - set(previous_dependency_ids):
self.request_node(new_dependency, ball, user)
# OR IF THE SAVED NODE IS A BRAND NEW NODE, we have to include all the deps
except Exception as error:
# stuff didn't work, send error back to user
print('ERROR: '+str(error))
self.write_message({
'command': 'display-error',
'message': str(error),
})
def update_our_DAG():
# 1. grab nodes and edges from database
all_node_dicts = list(Mongo("math", "nodes").find())
# 2. create a networkx graph with the info...
global our_DAG
our_DAG = nx.DAG()
for node_dict in all_node_dicts:
node = create_appropriate_node(strip_underscores(node_dict))
our_DAG.add_n(node)
def make_app():
return Application(
[
url('/', RedirectHandler, {"url": "index.html"}, name="rooth"),
url('/websocket', SocketHandler),
url('/json', JSONHandler, name="jsonh"),
url(r'/index(?:\.html)?', IndexHandler, name="indexh"),
# captures anything at all, and serves it as a static file. simple!
url(r'/(.*)', StaticHandler, {"path": "../www/"}),
],
# settings:
debug=True,
)
def make_app_and_start_listening():
# enable_pretty_logging()
application = make_app()
# by listening on the http port (default for all browsers that i know of),
# user will not have to type "http://" or ":80" in the URL
application.listen(80)
# other stuff
IOLoop.current().start()
if __name__ == "__main__":
# 0. create a global mongo object for later use (for upserts in the future)
our_mongo = Mongo("math", "nodes")
# 1 and 2
update_our_DAG()
axioms = [our_DAG.n(node_id) for node_id in ['set', 'multiset', 'vertex']]
# 3. launch!
make_app_and_start_listening()
I've tried everything and it's still an issue. WHY is this a syntax error? What is the best way to fix this?
It is not a SyntaxError but a SyntaxWarning. Python warns that you're using our_mongo variable before a global our_mongo within the function.
Syntactically it does not actually matter on which line of the function the global statement is; but the idiomatic way would be to use global before the first access.
Another issue altogether is that you have multiple global our_mongo statements, where single would do, and also that you do not even need the global at all - it is only for the case when you want to assign a new value to the global variable; i.e.
def foo():
global bar # this line is required for the next line
# to change the global variable instead of
# the local variable
bar = 42
Thus, just remove all global statements altogether from your on_message, they're unnecessary.
The only reason a name is declared global in a function is so that it will be bound in global scope instead of local scope; when accessing a name the global scope is always searched regardless. Since your code never binds our_mongo within any function there is no reason to declare it global in the first place.
Related
I have the following code to enable the file browser using blender:
import bpy
import os
from bpy.props import StringProperty
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator
sel = ''
class OpenBrowser(bpy.types.Operator):
bl_idname = "open.file"
bl_label = "Select Excel File"
bli_description = "Simulation output excel file"
filter_glob: StringProperty(default = '*.xls;*.xlsx',options = {'HIDDEN'})
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
#somewhere to remember the address of the file
def execute(self, context):
global sel
sel = self.filepath
#self.selected_file = self.filepath
#display = "filepath= "+self.filepath
#print(display) #Prints to console
#Window>>>Toggle systen console
return {'FINISHED'}
def invoke(self, context, event): # See comments at end [1]
context.window_manager.fileselect_add(self)
global sel
sel = self.filepath
#Open browser, take reference to 'self'
#read the path to selected file,
#put path in declared string type data structure self.filepath
return {'RUNNING_MODAL'}
# Tells Blender to hang on for the slow user input
bpy.utils.register_class(OpenBrowser)
#Tell Blender this exists and should be used
# [1] In this invoke(self, context, event) is being triggered by the below command
#but in your script you create a button or menu item. When it is clicked
# Blender runs invoke() automatically.
#execute(self,context) prints self.filepath as proof it works.. I hope.
bpy.ops.open.file('INVOKE_DEFAULT')
print(sel)
The issue I am facing is that I have declared a global variable sel to which I want to save the filepath selected from the user when running the code. However, when I run the script I see that sel has not changed and it is as it was initialized. Could someone please help me on how to access from the class the self.filepath variable? What am I doing wrong here?
If I understand correctly, you want to store that value for later.
I'm not sure why 'sel' doesn't even update in your case, but I think the more correct way would be to use a property like so:
import bpy
# Assign a custom property to an existing type.
bpy.types.Scene.my_sel_value = bpy.props.StringProperty(name="Sel")
# Set property value.
bpy.context.scene.my_sel_value = "Foo"
# Get property value.
print(bpy.context.scene.my_sel_value)
Properties can be added to all ID types, but for "global" values, bpy.types.scene us ussualy used. Though there can be multiple scenes in one project and they will have separate values. Property values are stored when Blender closes.
If you are making an addon, you can also store your value in Addon Preferences. This value will be the same for all blender projects.
My code is below. trying to print the htmlStr inside the function. Is there any way
import urllib.request
import re
url = 'http://dummy.restapiexample.com/api/v1/employees'
def testhtml(self):
response = urllib.request.urlopen(url)
htmlStr = response.read().decode('ISO-8859-1')
with open("html.csv","a+") as file:
file.write(htmlStr)
pdata = re.findall(r'"employee_name":"(\'?\w+)"', htmlStr)
return pdata
print (htmlStr) I did outside the function thrown error
when I did print (htmlStr) got the error NameError: name 'htmlStr' is not defined
You're getting an error because you're trying to access a local variable outside of its domain.
Here's what this looks like in your code:
# 1. Begin creating your function
def testhtml(self):
# 2. This is a local environment.
# Any variables created here will not be accessible outside of the function
response = urllib.request.urlopen(url)
# 3. The local variable `htmlStr` is created.
htmlStr = response.read().decode('ISO-8859-1')
with open("html.csv","a+") as file:
# 4. Your local variable `htmlStr` is accessed.
file.write(htmlStr)
pdata = re.findall(r'"employee_name":"(\'?\w+)"', htmlStr)
return pdata
# 5. Your function is now complete. The local variable `htmlStr` is no longer accessible.
Does that make sense?
If you want to print your function (while debugging) you can place a print statement in the function. (Just make sure to eventually remove it to prevent disorganized console readouts.) If you need to access the variable outside of the function, consider including in the output.
I am having trouble assigning a variable as global (i think this is my problem, at least).
Heres a representation of my code:
def get_alert():
global subject
# ...code ...
subject = # unread email's subject line
while True:
try:
get_alert()
except EOFError:
get_alert() # try again
else:
if subject == 'specific message here'
# ...code...
From what i've read assigning the variable as global at the top of the get_alert function should allow me to reference it in the while loop, however running the program it tells me, 'NameError: name 'subject' is not defined' for the subject in the while loop
You have to define subject before you use it, if you add
subject = None
at the beginning of your script, preferable after the imports, I think that will work.
My app has a simple process, the user uploads a gif file and then the gif is conveted to frames that are saved as objects. For the upload_to part of my gif, I run a function content_file_name() that uses uuid to create a folder path. I want the image frames to be saved to the same folder as the gif. Problem is, I can't set the path as a variable as much as I try. The variable needs to be defined first, but if I define it, it doesn't change no matter what I do. Here's what I got now:
currentFilePath = '' # Defining the variable
def content_file_name(instance, filename):
ext = ''.join(filename.split())[:-4]
foldername = "%s/%s" % (uuid.uuid4(), ext)
store_random_path('/'.join(['documents', str(foldername)])) # Running a function to change the variable
return '/'.join(['documents', str(foldername), filename])
def store_random_path(path):
currentFilePath = str(path) # The variable should be changed here
class Document(models.Model):
docfile = models.ImageField(upload_to=content_file_name)
def create_documentfiles(self):
gif = Image.open(self.docfile.path)
frames = [frame.copy() for frame in ImageSequence.Iterator(gif)]
basename, _ext = os.path.splitext(self.docfile.name)
for index, frame in enumerate(frames):
buffer = BytesIO()
frame.convert('RGB').save(fp=buffer, format='JPEG')
destname = "{}{}.png".format(basename, index)
finalImage = InMemoryUploadedFile(buffer, None, destname, 'image/jpeg', frame.tell, None)
imageToSave = DocumentImage(imagefile=finalImage)
imageToSave.save()
class DocumentImage(models.Model):
imagefile = models.ImageField(upload_to=currentFilePath) # Trying to save using the variable as path
image = models.ForeignKey(Document, related_name='Image', null=True, on_delete=models.CASCADE)
So, when the DocumentImage gets saved, it should have seen the variable as path, but it doesn't. Instead it just saves to the initially declared '' which is the root of my media file. Not sure if what I'm trying is possible in Python/Django. I've just started learing Python a month ago. Thank you for your time.
You are assigning to a global variable inside a function. You need to use the global keyword for that or you could refactor your code to not use any global variable (see Why are global variables evil?). This is not specific to Django.
The wrong way
global_var = ''
def function():
global_var = 'hello' # Local variable created due to assignment
Here global_var is still ''
The Correct way
global_var = ''
def function():
global global_var
global_var = "hello" # Assignment to the global variable
Here global_var is "Hello"
But all you've done is to set a local variable inside store_random_path. You haven't even returned that variable, let alone changed the global variable with the same name.
But you must not use global variables like this anyway. That would cause serious bugs as any future request would get the same value of the global variable. Don't do this.
I'm not sure why you are trying to set this variable in the first place. You have access to the Document, which contains the docfile which has its path correctly set. You should use that to calculate the path of the frames.
I know that this question looks exactly like so many other on here, because I just read them all and they all say to do what I already tried, and it hasn't worked (or I'm missing a subtle difference with my situation). Here is my situation:
I am writing a scraper using Scrapy and Python 2.7.11, and my code looks like this (this is a copy and paste with irrelevant lines omitted, but I can re-add them upon request):
class LbcSubtopicSpider(scrapy.Spider):
...omitted...
rawTranscripts = []
rawTranslations = []
def parse(self, response):
#global rawTranscripts, rawTranslations
rawTitles = []
rawVideos = []
for sel in response.xpath('//ul[1]'): #only scrape the first list
...omitted...
index = 0
for sub in sel.xpath('li/ul/li/a'): #scrape the sublist items
index += 1
if index%2!=0: #odd numbered entries are the transcripts
transcriptLink = sub.xpath('#href').extract()
#url = response.urljoin(transcriptLink[0])
#yield scrapy.Request(url, callback=self.parse_transcript)
else: #even numbered entries are the translations
translationLink = sub.xpath('#href').extract()
url = response.urljoin(translationLink[0])
yield scrapy.Request(url, callback=self.parse_translation)
print rawTitles
print rawVideos
print rawTranslations
def parse_translation(self, response):
global rawTranslations
for sel in response.xpath('//p[not(#class)]'):
rawTranslation = sel.xpath('text()').extract()
rawTranslations.append(rawTranslation)
This will return an error any time either "print rawTranslations" or "rawTranslations.append(rawTranslation)" is called because the global "rawTranslations" is not defined.
As I said before, I have looked into this pretty extensively and pretty much everyone on the internet says to just add a "global (name)" line to the beginning of any function you'd use/modify it in (although I'm not assigning to it ever, so I shouldn't even need this). I get the same result whether or not my global lines are commented out. This behavior seems to defy everything I've read about how globals work in Python, so I suspect this might be a Scrapy quirk related to how parse functions are called through scrapy.Request(....).
Apologies for posting what appears to be the same question you've seen so much yet again, but it seems to be a bit twisted this time around and hopefully someone can get to the bottom of it. Thanks.
In your case the variable you want to access is not global, it is in the scope of the class.
global_var = "global"
class Example:
class_var = "class"
def __init__(self):
self.instance_var = "instance"
def check(self):
print(instance_var) # error
print(self.instance_var) # works
print(class_var) # error
print(self.class_var) # works, lookup goes "up" to the class
print(global_var) # works
print(self.global_var) # works not
You only need the global keyword if you want to write to a global variable. Hint: Don't do that because global variables that are written to bring nothing but pain and despair. Only use global variables as (config) constants.
global_var = "global"
class Example:
def ex1(self):
global_var = "local" # creates a new local variable named "global_var"
def ex2(self):
global global_var
global_var = "local" # changes the global variable
Example().ex1()
print(global_var) # will still be "global"
Example().ex2()
print(global_var) # willnow be "local"
if you want to use variable in class, you can use self.xxx
class A:
... var = []
... def test(self):
... self.var.append(10)
... print self.var