Python - cannot access class property - python

I'm writing a class to access a mySQL db from python.
Here's the code:
#!/usr/bin/python
import MySQLdb
import configparser
class db():
def __init__(self):
try:
self.handler = MySQLdb.connect(host="localhost", user=user, passwd=passwd, db=dbname)
self.cur = self.handler.cursor()
except:
print "Couldn't connect to db"
def query(self, query):
self.lastQuery = query
self.res = self.cur.execute(query)
def close(self):
self.handler.close()
When I'm trying to call the class, it give me the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "db.class.py", line 6, in <module>
class db():
File "db.class.py", line 25, in db
self.res = self.cur.execute(query)
NameError: name 'self' is not defined
I've been searching and commonly there's people that forget to define the method with 'self' as an argument. But I'm including it.
Could anyone help me?
Thanks.
UPDATE:
I checked whitespaces and tabs and that is not the problem.

Your code has mixed tabs and spaces, causing Python to get confused about what statements are at what indentation level. The assignment to self.res has ended up at class level, outside of the method it was intended to be a part of.
Stop mixing tabs and spaces. Turn on "show whitespace" in your editor to make the problem more visible, and consider running Python with the -tt flag to give an error on ambiguous mixing of tabs and spaces.

Related

Python set self-variables by other class using cls?

I wonder if it is possible to set variables of a class by a different class using cls?
The story behind it:
I'm writing tests for different purposes but see that one part of the setup is the same as in an already existing class. So I would do the setUp by the already existing one:
The original code:
class TestBase(unittest.TestCase):
def setUp(self):
self.handler = txt.getHandler(hcu.handler3())
self.curves = self.handler.curves()
self.arguments = (getInit())
self.ac = self.connect2DB(self.arguments)
self.au = AutoUtils()
This has worked well so far.
Now in my TestClient I'd like to make use of that:
from .testsDB import TestBase as tb
class TestClient(unittest.TestCase):
def setUp(self):
tb.setUp()
And modified in the TestBase the setUp to the following:
#classmethod
def setUp(cls):
cls.handler = txt.getHandler(hcu.handler3())
cls.graph = cls.handler.curves()
cls.argv = (getInit())
cls.ac = cls.connect2DB(cls.arguments)
cls.au = AutoUtils()
But I'm getting an error as soon as I use one of the values defined in the variables of the TestClient-class:
def test_Duplicates(self):
self.testDB = self.ac.connect(self.ac.client, self.arguments[4])
With the error:
In test_Duplicate (Curves.tests_client.TestClient) :
Traceback (most recent call last):
File "/home/qohelet/Curves/tests_client.py", line 49, in test_Duplicate
self.testDB = self.ac.connect(self.ac.client, self.arguments[4])
AttributeError: 'TestClient' object has no attribute 'ac'
Is it actually possible what I'm trying?
EDIT:
After writing this and seeing the answers I did another review. Yes indeed there is a circular issue I'm having.
TestBase has the function connect2DB which will be executed on setUp.
If it refers to itself (as in the original) it's fine.
If I replace the self with cls it will try to execute TestClient.connect2DB in the setUp - which does not exist. So it would require self again as putting connect2DB into TestClient is not an option.
How to solve that?
Surely your new class should just inherit the setup()?
from .testsDB import TestBase as tb
class TestClient(tb):
def test_Duplicates(self):
self.testDB = self.ac.connect(self.ac.client, self.arguments[4])
The whole point of inheritance is that you don't modify what you inherit from. Your new class should just make use of what is supplied. That is why inheritance is sometimes called programming by difference.

Why it says that super() takes atleast 1 argument

class Member():
def __init__(self, MemberName, MemberID, SubcribtionPaid):
self.__MemberName = MemberName
self.__MemberID = MemberID
self.__SubcribtionPaid = False
def SetMemberName(self):
print(MemberName,self.__MemberName)
def SetMemberID (self):
print(MemberID,self.__MemberID)
def SetSubcriptionPaid(self):
print(SubcribtionPaid,self.__SubcribtionPaid)
class Jmember(Member):
def__init__(self,MemberName,MemberID,SubcribtionPaid,DateofJoining):
super().__init__(MemberName,MemberID,SubcribtionPaid)
self.__DateofJoining = DateofJoining
def SetDateofBirth(self):
print(DateofBirth,self.__DateofJoining)
NewMember = Jmember("Armeen","1245","True","12/3/2015")
NewMember.SetMemberName()
NewMember.SetMemberID()
NewMember.SetSubcriptionPaid()
NewMember.SetDateofJoining()
I basically copy pasted the code.I used pycharm. I still dont get how to use code block. I dont know what to do.
Sorry if i caused a problem.
I wrote a code in python,where one class inheritates the attributes of another class. When i run the code , error occurs on line 26 saying that super() takes atleast 1 argument .Even though i wrote the arguments. Did I make a mistake there. The code, the traceback
I want to see the output of the new member that includes member name, id , subcribtion paid and date of joining. But error is shown.
Updated my post to reflect your posted code:
You said that you are using PyCharm. pay attention to the red squiggly lines under sections as they are pointing out errors.
First error: you did not have a space between def and init
def__init__(self, MemberName, MemberID, SubcribtionPaid):
Second Error: found in your class function calls:
You do not have to call the class that is essentially what (self) is doing
def SetMemberName(self):
print(MemberName,self.__MemberName)
Third error: was found in your Traceback
You were trying to call a function that you forgot to create
Traceback (most recent call last):
File "/Users/sumbody/Projects/Python/MemberTest2/main.py", line 29, in <module>
NewMember.SetDateofJoining()
AttributeError: 'Jmember' object has no attribute 'SetDateofJoining'
Here is the working code:
class Member():
def __init__(self, MemberName, MemberID, SubcribtionPaid):
self.__MemberName = MemberName
self.__MemberID = MemberID
self.__SubcribtionPaid = False
def SetMemberName(self):
print(self.__MemberName)
def SetMemberID (self):
print(self.__MemberID)
def SetSubcriptionPaid(self):
print(self.__SubcribtionPaid)
class Jmember(Member):
def __init__(self,MemberName,MemberID,SubcribtionPaid,DateofJoining):
super().__init__(MemberName,MemberID,SubcribtionPaid)
self.__DateofJoining = DateofJoining
def SetDateofBirth(self):
print(self.__DateofJoining)
def SetDateofJoining(self):
print(self.__DateofJoining)
NewMember = Jmember("Armeen","1245","True","12/3/2015")
NewMember.SetMemberName()
NewMember.SetMemberID()
NewMember.SetSubcriptionPaid()
NewMember.SetDateofJoining()
Some advice, when learning to code and debug your own code, it is not a bad thing to take some code that runs and then break it. It sounds weird, but in doing so you will learn to recognize errors when seen in the editor and at runtime. Happy coding!

Declaration of CherryPy Tool fails

I'm trying to declare a new tool to the CherryPy toolbox following the examples from the docs: Docs CherryPy Tools.
According to the examples I have written:
import cherrypy
def myTool():
print ("myTool")
class Root(object):
#cherrypy.expose
#cherrypy.tools.mytool()
def index(self):
return "Hello World!"
if __name__ == '__main__':
cherrypy.tools.mytool = cherrypy.Tool('before_finalize', myTool)
cherrypy.quickstart(Root(), '/')
This results in the following error:
Traceback (most recent call last):
File "server.py", line 6, in <module>
class Root(object):
File "server.py", line 8, in Root
#cherrypy.tools.mytool()
AttributeError: 'Toolbox' object has no attribute 'mytool'
However if I change the notation to the following it works as expected.
import cherrypy
def myTool():
print ("myTool")
class Root(object):
#cherrypy.expose
def index(self):
return "Hello World!"
index._cp_config = {'tools.mytool.on': True}
if __name__ == '__main__':
cherrypy.tools.mytool = cherrypy.Tool('before_finalize', myTool)
cherrypy.quickstart(Root(), '/')
The docs says that both methods have the same effect, but not in my case. If anyone knows what I'm doing wrong I'll be very grateful.
The tool should not be defined globally, hence the #cherrypy.tools.mytool() notation.
I'm using python 3.6.
The problem is the misunderstanding of the evaluation order of python (top-down), at the time the class is defined the tool has not been defined.
You can define the tool in another file import at the top (before the class definition) and it should work.
The second form works, because the configuration is done indirectly using strings in the config, not the real tool objects.

Python Using mysql connection from super class

Below is just example code that provides the error I am hoping to get help on fixing, or getting an understanding of a better way to write this. I have a mysql "super" class called mysql_connection. In this class, the connection to the database is made. I also have a few methods within it. One that simply runs "select version()" to show that the connection/query works. I then have a "chktable" method which in this example instantiates a new subclass called "table" which inherits the super class. After instantiating the class, I then call a method within the subclass which attempts to use the the query method in the superclass to run "show tables like 'tbl name'". This is where I get an error.
import mysql.connector
from mysql.connector import errorcode
from mysql.connector.cursor import MySQLCursor
class mysql_connection(object):
def __init__(self, **kwargs):
self.connection_options = {}
self.connection_options['user'] = 'root'
self.connection_options['password'] = ''
self.connection_options['host'] = '192.168.33.10'
self.connection_options['port'] = '3306'
self.connection_options['database'] = "test"
self.connection_options['raise_on_warnings'] = True
self.connect()
def connect(self):
try:
self.cnx = mysql.connector.connect(**self.connection_options)
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print "Something is wrong with your user name or password"
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print "Database does not exists"
else:
print err
def query(self, statement, data=''):
cursor = MySQLCursor(self.cnx)
cursor.execute(statement)
result = cursor.fetchall()
cursor.close
return result
def get_version(self):
print self.query("select version()")
def chktable(self, tb_name):
tab = table(name=tb_name)
tab.check_table()
class table(mysql_connection):
def __init__(self, **kwargs):
self.name = kwargs['name']
def check_table(self):
return super(table, self).query("show tables like '{}".format(self.name))
conn = mysql_connection()
conn.get_version()
conn.chktable("test")
The error that I get is:
$ python example.py
[(u'5.1.73',)]
Traceback (most recent call last):
File "example.py", line 50, in <module>
conn.chktable("test")
File "example.py", line 39, in chktable
tab.check_table()
File "example.py", line 46, in check_table
return super(table, self).query("show tables like '{}".format(self.name))
File "example.py", line 28, in query
cursor = MySQLCursor(self.cnx)
AttributeError: 'table' object has no attribute 'cnx'
I don't fully understand calling back to the super class and how it works with subclasses, so that is likely my issue. I'd also like to know if there is maybe a better way to accomplish this. I was thinking I could get rid of the subclass altogether, but I like the subclass I made so I feel there should be a way around it. A secondary thing I could try would be to put the subclass inside the master class, but I don't think that is correct.
As Jon points out, this is not an appropriate use of inheritance. That is for "is-a" relationships: ie Dog inherits from Animal, because a dog is an animal. But a table is not a connection: a table might use a connection, but that simply means you should assign an instance of the connection to an instance variable in table.
Also, in an inheritance relationship there is usually no good reason for a superclass to know about its subclasses, as you have in the chktable method.
(The actual bug you're seeing is because you haven't called the superclass method in table's __init__, but it's better to fix your structure.)

argument count syntax error in Python

I'm getting a syntax error trying to make a Federated Table Builder.
Here's the offended interpreter:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "federatedTableBuilder.py", line 7, in <module>
local_public_files.generate()
File "localViewDefinition.py", line 22, in generate
self.generate_for_host(conn)
File "localViewDefinition.py", line 17, in generate_for_host
self.conn.doQuery(rsaconn,self.query)
TypeError: doQuery() takes exactly 2 arguments (3 given)
and the offending code:
import mysql as sql
from connector import Connector
import io
import traceback
class LocalViewDefinition:
...insert variables...
def doQuery(connection, query):
try:
cursor = MySQLdb.cursors.Cursor(connection)
cursor.execute(query)
except: #figure out how to handle generic and sql errors separately
traceback.print_exc()
Do you have any idea about the cause?
For class methods, Python takes an additional first argument to refer to the instance of the class. The convention is to use the word self:
def doQuery(self, connection, query):
try:
cursor = MySQLdb.cursors.Cursor(connection)
cursor.execute(query)
except: #figure out how to handle generic and sql errors separately
traceback.print_exc()
This requirement to refer to the instance of the class is because "explicit is better than implicit" in Python (cf. import this).
The other answers have already covered the fact that your instance method needs to have self1 as the first argument. However, it is worth noting that an instance method which doesn't use self maybe shouldn't be an instance method at all ...
class Example(object):
def instance_method(self):
print "I need self: %s" % self
#staticmethod
def static_method():
print "I don't need self."
#classmethod
def class_method(cls):
print "I use the class, not the instance: %s" % cls
Example.static_method() # I don't need self.
Example.class_method() # I use the class, not the instance: ...
e = Example()
e.instance_method() # I need self: ...
# can call staticmethods and classmethods from an instance as well:
e.static_method() # I don't need self.
As a final word, staticmethods in particular aren't generally super useful. Most of the time, a module level function without a class will due just fine.
1The name "self" is just convention -- You could use any name you like, but I wouldn't suggest it
You need to add another argument - name it "self" - in the method definition.
def doQuery(self, connection, query)
add self to def doQuery(connection, query)
def doQuery(self, connection, query):
that is the python class object reference.

Categories