Scope of Objects Passed as Arguments - Python - python

I want to send a session object of sqlalchemy to a function of another class .
From class OraDialog's function oraconnect to class oraconn's assign function .
Actually My need is to use the session object in oraconn's another function map
I can't send the session object directly to map function because it is a slot - it is triggered before .
I intended to define the assign function primarily to get the session object.
The Error : ( including print statements )
<sqlalchemy.orm.session.Session object at 0x030808F0>
<sqlalchemy.orm.session.Session object at 0x030808F0>
This is in assign
None
This is in map
Traceback (most recent call last):
File "C:\Users\Arul\Desktop\dbvis\oraconn.py", line 44, in map
for t in self.s.query(tables):
AttributeError: 'NoneType' object has no attribute 'query'
The oraconn class's assign and map functions :
def assign(self,s):
self.s=s
print self.s
print "This is in assign"
def map(self):
print self.s
print "This is in map"
self.table_no=0
for t in self.s.query(tables):
self.table_no=self.table_no+1
table_list.append(t.table_name)
self.item=QtCore.QStringList()
for c in self.s.query(columns):
self.item.append(c.column_name)
self.ui.list_col.addItems(self.item)
SO ,
The assign function receives the object properly . But the map function can't use it - It says Nonetype
My Question :
Two functions of same class can't use an object ?
I must have done something silly - so plz point out......
( I'm using windows7 / python 2.6 / PyQt4 /sqlalchemy /cx_oracle)
Edit :
The calling class :
class OraDialog(QtGui.QDialog):
def __init__(self,parent=None):
QtGui.QDialog.__init__(self,parent)
self.odia=Ui_Dialog()
self.odia.setupUi(self)
self.uiobj=oraconn()
QtCore.QObject.connect(self.odia.but_con,QtCore.SIGNAL('clicked()'),self.uiobj.oraconnect)
def oraconnect(self):
self.setVisible(0)
eng_str="oracle://"+self.odia.line_user.text()+":"+self.odia.line_pass.text()+"#localhost:1521/"+self.odia.line_sid.text()+"?mode="+self.odia.line_role.text()
engine_str=str(eng_str)
engine=create_engine(engine_str)
Session=sessionmaker(engine)
self.s=Session()
print self.s
Problem Solved :
The problem is - i've created two instances and passed from one to another .
Corrected code :
oraconn.assign(myapp,self.s)
where
oraconn -> class
assign -> function of oraconn
myapp -> instance of oraconn , declared for main application
self.s -> the argument i wanted to pass
Thank you Kirk ....

If you're using Qt, then this is likely a GUI app. Maybe there are threading issues; maybe self refers to different objects. It's hard to tell with only what you've given us. Before you go any further, add:
print self
near the top of each method. At least then you can confirm whether both are operating on the same object.
In OraDialog.init, you're saying self.uiobj=oraconn(). Is that the object that's giving you problems? If so: notice that you're creating at as an instance variable, so that each OraDialog object has a different .uiobj object. Could you try making that a class variable by writing:
class OraDialog(QtGui.QDialog):
uiobj = oraconn()
def __init__() [...]
instead? That is, define uiobj as belonging to all instances of the class, not just one instance.

The code you have posted seems to be okay, I can't spot any obvious mistakes.
The problem must be on the calling side. As the self reference can be passed explicitly to methods (via OraDialog.map(my_object), where my_object could be anything) this perfectly possible. Also note that this has nothing to do with scoping.
You should check calling code of the map function. It is very likely it is called on a different object as assign.

Related

Are all methods are preceded by a dot(.) or just some of them. How do we define it needs a dot or not?

I was learning Python by using Python Crash Course and came upon this String and Method thing: It only said that the dot(.) after name in name.title() tells Python to make the title() method act on the variable name.
Not always, you can create a method dynamically:
from types import MethodType
def fn(x):
return x.var
class A:
def __init__(self):
self.var = 20
obj = A()
method_ = MethodType(fn, obj)
print(method_)
print(method_())
output :
<bound method fn of <__main__.A object at 0x000001C5E3F01FD0>>
20
A method is an instance of type MethodType and also it has an object bound to it, when method gets called, it's first parameter will always get filled with that object. Here fn() function's first parameter (x) will be filled with obj object.
The above answer is precise but i wanted to add to it.
Actually methods are functions that take objects as arguments and then return values based on that and as python is an Object Oriented Language therefore everything in python is an object.
When you call name.title():
then, python search for the title() method for the name object.And as all methods are designated to take the object as an argument:
`def title(self):
...+
`
This is what a method definition look like inside a class and the self argument here stands for the object calling the method.
And we do not have to specify it explicitly it is recognised by the python interpreter.
As in your case: name.title() the object calling the method title() is the name variable therefore here self is assigned the value of name that is the function call name.title() is equivalent to title(name) but the former is the correct syntax of calling the method whereas the latter one is for comprehesion purpose.
If you run title(name) it surely gonna raise an error.
But, as the title() method belongs to the str class you can always call str.title(name).
Hope i didn't confuse you instead of making it clearer...Happy coding..:)

Get a reference to an object

I am trying to create a class that can be given any object on construction and then will list all of that object's callable methods in an interactive prompt. I am using the PyInquirer module for the interactive prompt, and the inspect module to get all the methods of the given object.
I have so far succeeded in dynamically building the prompt for any given object, but my program gives the error Foo() takes 0 positional arguments but 1 was given when attempting to call one of the methods from the prompt.
I think the reason it crashes is that at the time of execution there are no more references to the object, so its reference count is at zero and the object is freed.
If I could get the class to keep hold of its own reference to the object, then this will solve the problem. For example
def __init__(self, object):
# Create a local reference the object
self.__object = &object
But this is invalid python.
How do I get a reference to the object (or manually increment the reference count, and manually decrement it in the __del__ function)?
Full source code for ObjectMethodTerminal.py can be found here https://gitlab.com/snippets/1939696
Change your sample class to this:
class A:
def Foo(self):
print("Hello")
def Bar(self):
print("World")
def Baz(self):
print("!")
Note the added self to the method parameters.
If you had tried this code first:
a = A()
a.Foo()
You would have found your error before going the long route of inspecting the class.

Python: Create a member that is a instance of its class

I am very confused that I did not directly found a topic about my concern:
I got the class RoadMark. In this class, I wanna create a member that is a specific instance of that class. But I am not able to call the constructor.
I tried:
calling the init function (but it has no return, so its worthless)
define the member as a function with the #property attribute (but these returns cannot have members, so worthless for an object)
Trying "solid = self.RoadMark..." (also not working)
Using a factory function to create the object (but in the method, RoadMark is also not defined)
Is there a way to solve my problem or do I have to outsource the "solid" variable?
Kind regards
You can assign it to the class member after the class definition.
class RoadMark:
...
RoadMark.solid = RoadMark()
Python code is executed as it is encountered. When the interpreter encounters the line class RoaMark:, it starts creating a new class object. Then it starts to run the code inside the class body to determine the attributes of the class. When the code in the body is running, the class object does not exist yet, so you can't access it. What you can do is wait until the class is created before assigning an attribute to it:
class RoaMark:
...
RoaMark.solid = RoaMark(...)

Why is extend method not working when i call it using list.extend?

When i call the extend method of list in python using list.extend(list_object) i get an error. Why is this happening? Instead of declaring an object of list class i am directly calling the extend using list.extend. the following is the code which i wrote.
l=list()
l2=[1,2,3,4]
print(list.extend(l2))# throws an error.I was under the impression that this is same as the below statement
print(l.extend(l2)) #doesnt throw an error
Also,
class student():
a=1
s=student()
s.a #prints 1.
student.a #also prints 1. Here the previous error isnt coming.
Why is this so?
Both cases are not the same.
In the first case, you're calling a method (a callable attribute) of a builtin class via the class and then an instance of the class. In the second case, you're accessing a non callable attribute of the class, via the instance and then via the class. Methods are callable and in order to call them, you need to respect the signature of the method, unlike the second case.
To use extend via the list class itself, you need to pass a list instance as first argument, as vanilla methods in Python usually require an instance as first argument:
list.extend(l, l2) # extends l with l2
Note that the instance is implicitly passed when you call extend via the instance in l.extend(l2).

Defining Python Functions in Google App Engine

I am new to python and am trying to define a function and then use it in Google App Engine - but I keep getting the error "Error: global name 'cache_email_received_list' is not defined" when I try to execute the function. Any help would be greatly appreciated, thanks.
Here is my function:
class EmailMessageHandler(BaseHandler2):
def cache_email_sent_list(): #set email_sent_list to memcache
email_sent_list = db.GqlQuery("SELECT * FROM EmailMessage WHERE sender =:1 ORDER BY created DESC", user_info.username)
if email_sent_list:
string1 = "email_sent_list"
email_sent_list_cache_id = "_".join((user_info.username, string1))
memcache.set('%s' % email_sent_list_cache_id, email_sent_list, time=2000000)
logging.info('**************email_sent_list added to memcache*********')
Here is where I am trying to call it:
if email_received_list is None and email_sent_list is not None:
params = {
'email_sent_list': email_sent_list,
}
cache_email_sent_list()
cache_email_sent_list() is a method of the class EmailMessageHandler therfore the method needs to pass in self a a parameter it will therefore look like this:
class EmailMessageHandler(BaseHandler2):
def cache_email_sent_list(self): #set email_sent_list to memcache
email_sent_list = db.GqlQuery("SELECT * FROM EmailMessage WHERE sender =:1 ORDER BY created DESC", user_info.username)
if email_sent_list:
string1 = "email_sent_list"
email_sent_list_cache_id = "_".join((user_info.username, string1))
memcache.set('%s' % email_sent_list_cache_id, email_sent_list, time=2000000)
logging.info('**************email_sent_list added to memcache*********')
Then when you call it from within the class EmailMessageHandler you have to do it like this:
self.cache_email_sent_list()
If however you are calling it from outside the class EmailMessageHandler you need to first create an instance and then call it using:
instanceName.cache_email_sent_list()
Just as an addition to the previous answers: In your post you define cache_email_sent_list() as a function defined in a class definition, which will not work. I think you are confusing instance methods, static methods and functions. There's a prominent difference between these three.
So, as a stylised example:
# instance method:
class MyClass(MySuperClass):
def my_instance_method(self):
#your code here
# call the instance method:
instance = MyClass() # creates a new instance
instance.my_instance_method() # calls the method on the instance
# static method:
class MyClass(MySuperClass):
#staticmethod # use decorator to nominate a static method
def my_static_method()
#your code here
# call the static method:
MyClass.my_static_method() # calls the static method
# function
def my_function():
# your code here
# call the function:
my_function() # calls your function
Indentation is part of Python syntax and determines how the interpreter handles your code. It takes a bit getting used to but once you've got the hang of it, it's actually really handy and makes your code very readable. I think you have an indentation error in your original post. Just add the correct indentation for the method cache_email_sent_list() and call it on an instance of EmailMessageHandler and you're good to go.
The problem has nothing to do with GAE.
The problem is that you've defined cache_email_sent_list as a method of the class EmailMessageHandler, but you're trying to call it as a top-level function. You can't do that. You need to have an instance of a EmailMessageHandler to call it on.
If you're trying to call it from another method of EmailMessageHandler, that instance should be available as self. For example:
self.cache_email_sent_list()
If you're trying to call it from elsewhere, it's up to you to figure out what instance you should be calling it on. For example:
handler_passed_as_param_to_this_function.cache_email_sent_list()
Note that your error message is about cache_email_received_list, but your code only has cache_email_sent_list. I'm guessing that you have parallel code, and the exact same error for both cases, but of course I could be guessing wrong—in which case you'll have to actually show us either the code that goes with your displayed error, or the error that goes with your displayed code…

Categories

Resources