Reputation: 96
I am trying to access cls.dates in both the methods defined in the class decorated with @classmethod
s. But below code gives me an error Database has no attribute dates
. I need help to access it in the methods.
class Database:
""" class that works with data storage and retrieval. """
def __init__(cls, file='D:\\vscode\\Python\\data.db'):
# initialise database with a file-name
cls.dates = {
1:31,
2:28,
3:31,
4:30,
5:31,
6:30,
7:31,
8:31,
9:30,
10:31,
11:30,
12:31
}
@classmethod
def add(cls, data):
connection = sqlite3.connect('D:\\vscode\\Python\\data.db')
c = connection.cursor()
c.execute('INSERT INTO mydata (accuracy, efficiency, day, month) VALUES (?, ?, ?, ?);', (data[0], data[1], data[2], data[3]))
connection.commit()
connection.close()
@classmethod
def get(cls, date):
(_day, _month) = tuple(map(int, date.split('-')))
#calculate low-expressions
if _day <= 3:
low_month = _month-1
low_day = cls.dates[low_month]-(3-_day)
else:
low_month = _month
low_day = _day-3
#calculate high-expression
if _day > cls.dates[_month]-3:
high_month = _month+1
high_day = _day - cls.dates[_month] + 3
else:
high_month = _month
high_day = _day + 3
# establish connection and retrive the data
connection = sqlite3.connect('D:\\vscode\\Python\\data.db')
c = connection.cursor()
c.execute('SELECT accuracy, efficiency, day, month FROM mydata WHERE day BETWEEN (?) AND (?) AND month BETWEEN (?) and (?);',(low_day, high_day, low_month, high_month))
to_plot = c.fetchall()
connection.close()
# return the data
return to_plot
I cannot access the dates attribute of the Database
class from any method.
Upvotes: 0
Views: 144
Reputation: 41180
You need to understand the difference between a class and an object. An object is an instance of a class. You can have many objects (instances) of the same class An object has all of the class's data and methods, but also it's own data.
classmethods run on the class. Instance methods run on the object. A classmethod can't access data from an object of the class because (among other reasons) there can be many objects of that class.
You have two options:
Make the classmethods instance methods (delete the @classmethod
decorator). Then, they are methods on the object and can access object level data.
Move the data you want to be accessible by the classmethods to the class (put it outside the init function).
Option 1:
class Database:
def __init__(self):
self.dates = {...}
def add(self, data):
logic(self.dates)
database = Database()
database.add(...)
Option 2:
class Database:
dates = {...}
@classmethod
def add(cls, data):
logic(cls.dates)
Database.add(...)
BTW, it is convention to refer to the first parameter of classmethods as cls
and the first parameter of instance methods as self
to avoid this very confusion.
Upvotes: 2