I just wanna create a class definition with a static field with a name. A file called exercises.py contains:
First error:
FAIL: test_00_packages (__main__.Ex00)
Traceback (most recent call last):
File "ex00.py", line 55, in test_00_packages
self.assertTrue("Exercise00" in globals())
AssertionError: False is not true
Later:
class Exercise00:
def __init__(self, STUDENT_NAME):
self.STUDENT_NAME = 'Name Name'
But if I try to print Exercise00.STUDENT_NAME I just get
NameError: name 'Exercise00' is not defined
But I guess I defined it?!
Here the complete error:
ERROR: test_01_static_field (__main__.Ex00)
----------------------------------------------------------------------
Traceback (most recent call last):
File "ex00.py", line 60, in test_01_static_field
print("[I] Name: " + Exercise00.STUDENT_NAME)
NameError: name 'Exercise00' is not defined
----------------------------------------------------------------------
My task is to create a class called Exercise00 with a static field STUDENT_NAME.
The line in ex00.py is:
def test_00_packages(self):
self.assertTrue("Exercise00" in globals())
Two problems:
The test class is in a separate file exercises.py; you need to import the relevant functionality from that file (from exercises import Exercise00) before the module contents are visible from ex00.py.
Once you fix that, you will get a different error. Like the name of the test says, you are supposed to be looking for a static field, i.e. something that belongs to the class itself. This code attaches STUDENT_NAME to instances of Exercise00.
I suppose you need to define STUDENT_NAME as a class-level field, not as an instance level attribute:
class Exercise00:
STUDENT_NAME = 'Name Name'
You can notice in the error message that the test calls class level field Exercise00.STUDENT_NAME:
print("[I] Name: " + Exercise00.STUDENT_NAME)
And you also need to import class Exercise00 in the test module:
from exercises import Exercise00
As soon as you add the import statement to the file with the test ex00.py, the class name string appears in globals() and the test passes.
Related
I have a script that takes note of tables that do not contain primary keys. At the end of the execution of this script I want to raise an error that prints sequentially prints the names of these tables.
class MissingPrimaryKeysError(Exception):
"""MissingPrimaryKeysError exception class"""
def __init__(self, missing_keys, message="Some primary keys are missing"):
self.missing_keys = missing_keys
self.message = message
print('The following tables are missing primary keys')
for pk in missing_keys:
print(pk)
tables_missing_pk = ['some_table', 'other_table']
if tables_missing_pk:
raise MissingPrimaryKeysError(tables_missing_pk)
I tried to overwrite the __init__ method of the base class Exception (shown above), but this does not result in my envisioned result. The envisioned result is as follows:
Traceback (most recent call last):
File "<filepath>", line 13, in <module>
raise MissingPrimaryKeysError(tables_missing_pk)
__main__.MissingPrimaryKeysError: The following tables are missing primary keys:
some_table
other_table
What is happening now is the following:
The following tables are missing primary keys
some_table
other_table
Traceback (most recent call last):
File "d:/git/DataLake.General.DataStore.Notebooks/notebooks/raw/ods/pks_test.py", line 13, in <module>
raise MissingPrimaryKeysError(tables_missing_pk)
__main__.MissingPrimaryKeysError: ['some_table', 'other_table']
It appears as if the logic in my custom __init__ function is indeed executed, and then the Exception is raised "normally" and just flat out printing the list. How can I get to the envisioned result?
Provide a __repr__ implementation that defines how you want your exception to be rendered when it's printed as part of a stack trace (or elsewhere):
class MissingPrimaryKeysError(Exception):
"""MissingPrimaryKeysError exception class"""
def __init__(self, missing_keys, message="Some primary keys are missing"):
self.missing_keys = missing_keys
self.message = message
def __repr__(self):
return (
self.message + ':\n'
+ '\n'.join(str(pk) for pk in self.missing_keys)
)
I have been using importlib to get the module from an imported python file and would like to get the line number where each class is defined in the python file.
For example I have something like this:
testSpec = importlib.util.spec_from_file_location("", old_file)
testModule = importlib.util.module_from_spec(testSpec)
testSpec.loader.exec_module(testModule)
Where old_file is a python file (lets call it old.py). Then using the inspect library I can find all of the classes from old.py in this way:
for name, obj in inspect.getmembers(testModule):
if inspect.isclass(obj):
print(name)
This gives me all of the created class names from old.py which is correct. However, what I would like to do is also get the line number where this class appears in old.py. I have tried to add this line in the if statement right after the print statement: print(inspect.getsourcelines(obj))
However, this errors out in this way:
File "old.py", line 665, in getfile
raise TypeError('{!r} is a built-in class'.format(object))
TypeError: <class '.exampleClassName'> is a built-in class
I am not sure why it considers this user-created class a built-in class, but is there another way that I can just get the line number where this class is defined in old.py? For example if old.py looks like this:
#test comment line 1
#test comment line 2
class exampleClassName:
test = 0
Then when I have the class object exampleClassName I would expect to print out 4 from inspect.getsourcelines(obj) since it is defined on line 4.
An option would be to loop through the file with open and .readline(), and see where the line matches class, then save the line (count) number and class name into a dict.
I'm trying to make a code to generate information on a certain subject when user input is given. The final goal is to make a version of the Pokedex, with all 800+ Pokemon identified. I currently have a class set up with the ability to add new Pokemon to it with ease. The problem lies in where I try to call information about each Pokemon.
class pokemon:
def __init__(self, id_num, name):
self.id_num = id_num
self.name = name
def information(self):
print(__name__.id_num)
Bulbasaur = pokemon("001", "Bulbasaur")
print("What Pokemon are you looking for today?")
poke = input()
pokemon.information(poke)
This is a trimmed version of the full class I used. What I wanted it to do was print the ID number of the Pokemon's name when the user inputs the name. In this example, typing "Bulbasaur" would have outputted "001". However, I receive this error:
C:\--->pokedex.py
What Pokemon are you looking for today?
Bulbasaur
Traceback (most recent call last):
File "C:\---\pokedex.py", line 13, in <module>
pokemon.information(poke)
File "C:\---\pokedex.py", line 7, in information
print(__name__.id_num)
AttributeError: 'str' object has no attribute 'id_num'
Any ideas on how to fix this? I want to avoid using if poke = "Bulbasaur": print(Bulbasaur.id_num) since I would need to do that for every Pokemon.
Inside of a method of the object you are interested in, you can just print id_num.
I've got 2 files : main.py and batsol.py
batsol.py contains a class and main.py is creating some instances from the class Batsol.
So I'll show you a concise version of my code...
class Batsol:
def __init__(self, addressCan = None, name = None) :
self.addressCan = addressCan
self.name = name
#other stuff ...
Then my main.py :
from batsol import Batsol
# other import and code ...
print(callable(Batsol))
bs1 = Batsol()
# code...
if len(listener.ring_buffer) == 0 :
for Batsol in tab_BS :
try:
print(tab_BS[Batsol])
except (IndexError):
pass
# code...
while(True) :
# for and if interlocked
print(callable(Batsol))
bs2 = Batsol()
The console shows :
True
False
Traceback (most recent call last):
File "./main.py", line 135, in <module>
bs2 = Batsol()
TypeError: 'int' object is not callable
the second part of the traceback is not linked to other stuff i'm doing in my code (thread not terminated properly... something like this) , in my opinion
Exception ignored in: <module 'threading' from '/usr/lib/python3.4/threading.py'>
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 1292, in _shutdown
t = _pickSomeNonDaemonThread()
File "/usr/lib/python3.4/threading.py", line 1300, in _pickSomeNonDaemonThread
if not t.daemon and t.is_alive():
TypeError: 'bool' object is not callable
WHY my object is not callable inside my tests loops ???
It drives me crazy...
Your shadowing occurs in this code fragment:
if len(listener.ring_buffer) == 0 :
for Batsol in tab_BS :
try:
print(tab_BS[Batsol])
except (IndexError):
pass
time.sleep(4)
for-in construct on sequences works as following:
Sequence is asked for next (first, second, ... last) element. Internal pointer keeps track of element in current iteration.
Element gets assigned to name on left side of "in".
Go to 1.
After loop finishes, Batsol is no longer your class, but last element from tab_BS.
I'd suggest getting a better IDE, or using good static code analysis tool (Pylint / Flake8 etc.) as this kind of error is easily detected by e.g. PyCharm (your code shadows name from outer scope).
Related: How bad is shadowing names defined in outer scopes?
I am trying to inherit a variable from base class but the interpreter throws an error.
Here is my code:
class LibAccess(object):
def __init__(self,url):
self.url = url
def url_lib(self):
self.urllib_data = urllib.request.urlopen(self.url).read()
return self.urllib_data
class Spidering(LibAccess):
def category1(self):
print (self.urllib_data)
scrap = Spidering("http://jabong.com")
scrap.category1()
This is the output:
Traceback (most recent call last):
File "variable_concat.py", line 16, in <module>
scrap.category1()
File "variable_concat.py", line 12, in category1
print (self.urllib_data)
AttributeError: 'Spidering' object has no attribute 'urllib_data'
What is the problem with the code?
You will need to define self.urllib_data prior to accessing it. The simples way would be to create it during initialization, e.g.
class LibAccess(object):
def __init__(self,url):
self.url = url
self.urllib_data = None
That way you can make sure it exists everytime you try to access it. From your code I take it that you do not want to obtain the actual data during initialization. Alternatively, you could call self.url_lib() from __init__(..) to read the data for the first time. Updating it later on would be done in the same way as before.