The format which I'm using to execute some code based on which class the variable 'tester' is appears not to be working. How can I write the code such that the variable 'var' in the class 'testClass()' is changed .
I have tried changing the format from "if tester == testClass():" to "if testClass() in [tester]:", but neither work nor return errors. Changing 'var = second' to 'var = "second"' doesn't appear to help either, and neither does removing any brackets.
The code is as follows:
class fillClass():
fill = True
class testClass():
var = "first"
filler = True
tester = testClass()
oldVar = tester.var
print(oldVar,"is older variable")
second = "second"
if tester == testClass():
class testClass():
var = second
filler = True
tester = testClass()
newVar = tester.var
print(newVar,"is newer variable")
I would expect the output
first is older variable
second is newer variable
>>>
but the actual output is
first is older variable
first is newer variable
>>>
How can I fix this issue?
Many thanks!
The problem lies with this if-clause: if tester == testClass(), which will always evaluate to false, since calling testClass() instantiates a completely new object of type testClass. You want to check of what instance a variable is by using the function isinstance().
This is what you want:
class fillClass():
fill = True
class testClass():
var = "first"
filler = True
tester = testClass()
oldVar = tester.var
print(oldVar,"is older variable")
second = "second"
if isinstance(tester,testClass):
class testClass():
var = second
filler = True
tester = testClass()
newVar = tester.var
print(newVar,"is newer variable")
You are comparing an instance of a class with a class which will not work. I don't know if this is what you want to check but if yes you should do like this:
Instead of:
if tester == testClass():
You have to use:
if isistance(tester, testClass()):
Also, in your code, you have never used the fillClass.
I am guessing that you want something like this:
class TestClass():
var = "first"
filler = True
tester = TestClass()
oldVar = tester.var
print(oldVar, "is older variable")
second = "second"
if tester.var == "first":
tester.var = second
newVar = tester.var
print(newVar, "is newer variable")
Please note that you should respect Python class name convention(capitalize camelcase) and you don't have to redefine your class again.
You should also know the difference between instance variables and class variables and you may want to use de class constructor:
class TestClass():
def __init__(self, var, filler=True):
self.var = var
self.filler = filler
Related
I've made a class as follow:
class Plugins:
def __init__(self):
pass
def voter_rep(self, loc, start_header, end_header):
self.loc = loc
ocr_xml = AbbyyXML(loc)
xml_doc = XMLDoc(ocr_xml, CONSTANTS)
xml_doc.split_words("", False)
self.start_header = start_header
self.end_header = end_header
header_pages = xml_doc.se_page(start_header, end_header)
## and stuff
voter_dict = {'Voter':[], 'Record_Key':[], 'Comments':[]}
## and stuff
return voter_dict, rep_dict
if I run the method function on its own and outside of the class it works totally fine, namely if I write the function as:
def voter_rep(loc, start_header, end_header):
ocr_xml = AbbyyXML(loc)
xml_doc = XMLDoc(ocr_xml, CONSTANTS)
xml_doc.split_words("", False)
header_pages = xml_doc.se_page(start_header, end_header)
## and stuff
voter_dict = {'Voter':[], 'Record_Key':[], 'Comments':[]}
## and stuff
return voter_dict, rep_dict
in the function alone I get rid of self and will just have voter_rep(loc, start_header, end_header) but when I want to call it from the class I do plugins.voter_rep(loc, start_header, end_header) which does not work, and it returns:
NameError: name 'plugins' is not defined
I wonder why is it that my function works on its own but not callable from the class?
You can do
plugins = Plugins()
loc = #some val
start_header = #some val
end_header = #some val
plugins.voter_rep(loc, start_header, end_header)
As the error message shows, you are using small 'p' instead of capital. Also since it is not a static function, so it is not good to call it via class name.
Plugins.voter_rep(loc, start_header, end_header)
Take note of the capital letter.
Lets say i have the following code:
class asd:
def __init__(self):
self.var = "default"
def changeagain():
xa = asd()
xa.var = "changed"
return xa
def change(objct:asd):
newobjc = changeagain()
objct = newobjc
print(objct.var)
test = asd()
change(test)
print(test.var)
what i expect as output is:
changed
changed
nonetheless i get:
changed
default
What is the problem?
What i must do to get the desired output?
Here, you are changing the value of an object's instance variable and expecting the change to b reflected in another object. Whereas it is not possible in the case of instance variables of objects.
As per your need, I've changed certain statements in your program :
class asd:
var = "default"
def changeagain():
xa = asd()
asd.var = "changed"
return xa
def change(objct:asd):
newobjc = changeagain()
objct = newobjc
print(objct.var)
test = asd()
change(test)
print(test.var)
class asd:
def __init__(self):
self.var = "default"
def changeagain(asd):
# xa = asd()
asd.var = "changed"
return asd
def change(asd):
newobjc = changeagain(asd)
objct = newobjc
print(objct.var)
test = asd()
change(test)
print(test.var)
I have commented out the object creation in the changeagain() and passed the object of the class for which you want to change the value.
Earlier you were passing an object of the class but changing the value for a different object.
Happy coding
I have the following class and I want the instance variable api_id_bytes to update.
class ExampleClass:
def __init__(self):
self.api_key = ""
self.api_id = ""
self.api_id_bytes = self.api_key.encode('utf-8')
I'd like to be able to have this outcome:
>>>conn = ExampleClass()
>>>conn.api_key = "123"
>>>conn.api_id = "abc"
>>>print(conn.api_id_bytes)
b'123'
>>>
I basically need the self.api_key.encode('utf-8') to run when an api_id is entered but it doesn't, it only does through the initial conn = ExampleClass().
I'm not sure what this is called so searching didn't find an answer.
Here's how you could do it by making api_id_bytes a property.
class ExampleClass:
def __init__(self):
self.api_key = ""
self.api_id = ""
#property
def api_id_bytes(self):
return self.api_key.encode('utf-8')
Now conn.api_id_bytes will always be correct for the current value of conn.api_key.
I need to get the object method who called another function. I don't want its name, but the actual object.
So far, I got this.
import inspect
def info():
stack_call = inspect.stack()
cls_method = stack_call[1][3]
cls_obj = stack_call[1].frame.f_locals["self"]
cls_members = inspect.getmembers(cls_obj)
my_obj = None
for el in cls_members:
if el[0] == cls_method:
my_obj = el[1]
break
print(my_obj)
class Bob:
def __int__(self):
pass
def jim(self):
info()
test = Bob()
test.jim()
It does what I want to do, but I don't like having to go through the list to find the right method with its name.
I tried many things, but can't see how to make it better.
Would anybody have a better version?
A little different:
def info():
stack_call = inspect.stack()
cls_obj = stack_call[1].frame.f_locals[list(stack_call[1].frame.f_locals.keys())[0]]
cls_method = getattr(cls_obj, stack_call[1][3])
print(cls_method)
I am learning Python out of a book and have written myself a long quiz/type game which prints a summary at the end. However, the summary looks for attributes that will not always exist depending on what choices have been made by the user.
I have abstracted this into a basic example to show what I am trying to do. Essentially, I just want to run an attribute error check, for every variable that does not have an attribute, create an attribute with a default value of N/A.
In the below example, I would want it to print:
Forename: Joe
Surname: Bloggs
Smith Test: N/A
Test 4: N/A
I created a class called CodeCleaner which I was going to use to set the N/A values, but got very stuck!
class QuestionSet(object):
next_set = 'first_set'
class ClaimEngine(QuestionSet):
def current_set(self):
last_set = "blank"
while_count = int(0)
quizset = Sets.subsets
ParentSet = QuestionSet()
while ParentSet.next_set != last_set and int(while_count)<50:
quizset[ParentSet.next_set].questioning()
while_count = while_count+1
class FirstSet(QuestionSet):
def questioning(self):
self.value1 = raw_input("Forename:\n")
QuestionSet.next_set = "second_set"
class SecondSet(QuestionSet):
def questioning(self):
self.value2 = raw_input("Surname:\n")
if self.value2 == "Smith":
self.value3 = "He's a Smith!"
self.value4 = "Test val 4"
QuestionSet.next_set = "summary"
else:
QuestionSet.next_set = "summary"
class CodeCleaner(QuestionSet):
def questioning(self):
mapping = Sets()
sets = mapping.subsets
variable_list = {
[sets['first_set']].value1,
[sets['second_set']].value2,
[sets['second_set']].value3,
[sets['second_set']].value4
}
#while key_no < 4:
# try:
# print variable_list
# except AttributeError:
class Summary(QuestionSet):
def questioning(self):
mapping = Sets()
sets = mapping.subsets
print "Forename:",sets['first_set'].value1
print "Surname:",sets['second_set'].value2
print "Smith Test:",sets['second_set'].value3
print "Test 4:",sets['second_set'].value4
exit(0)
class Sets(object):
subsets = {
'first_set': FirstSet(),
'second_set': SecondSet(),
'summary': Summary()
}
run = ClaimEngine()
run.current_set()
I feel quite lazy asking this question, however, I've been wrestling with this for a few days now! Any help would be appreciated.
I'm not sure I go exactly your approach, but you can implement a __getattr__ method in an object that would be called when the attribute is not found:
class A(object):
def __getattr__(self, name):
print("Creating attribute %s."%name)
setattr(self, name, 'N/A')
Then:
>>> a = A()
>>> a.a
Creating attribute a.
>>> a.a
'N/A'