cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
649
Views
1
Helpful
14
Replies

Scope of Class Obj in Python

dalthami
Cisco Employee
Cisco Employee

Hello.

This is the first time I've tried to use Developer Hub community Support.  Please let me know if I need to take a different approach.

Here is my problem.

# I create a class and inside the class I only have integer variables.  
# I then create an object from the class and go into a while loop, parsing json data and incrementing counters in obj.
# However, when I exit the while loop and execute the printme instance method, all the integer variables are always zero.
# Why isn't the object (instance of the class) keeping the values?
# The structure of the script is like this
class VerdictStats:
def __init__(self):
self.noVerdict = 0
self.phishing = 0
<etc for more variables>

def printme(self):
print(f" noVerdict: {self.noVerdict}")
print(f" Phishing: {self.phishing}")
<etc for other variables>
return

# I then create the object in Global Scope.
verdictObj = VerdictStats()

# I then enter a while loop and query Cisco Email Threat Defense (ETD) via API and parse the json an increment the counters
while total_messages_retrieved < total_messages_to_scan:

response = requests.request(... send the query and receive the response...)
response_dict = json.loads[response.text)
# then get message list out of dict
# then loop through all the messages
# all this works fine - I can see all the data if I print it
# Now increment the instance object if I see certain things in message json data
try:
verdict = message["verdict"]
if verdict == "phishing":
verdictObj.phishing += 0
<etc for other verdicts>
# the loop continues through all messages
# script falls out of while loop and back into Global scope
# I then call the printme instance method and all the counters are zeros
verdictObj.printme()
# and the output is all zeros
# can anyone tell me why the instance object is not keeping the data?


 

14 Replies 14

Hey @dalthami  you are using the += operator to increment the counters and so this operator creates a new object with the updated value, but it does not assign the new object to the verdictObj variable in your code. Try this, it will  increment the phishing attribute on the verdictObj instance.

if verdict == "phishing":
  verdictObj.phishing += 1

  Hope this helps.

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

Hi bigevilbeard.
My mistake in my posting (too much pseudo-code in trying to describe the problem – sorry about that).
Here is the actual code. I’m doing exactly what you suggest.

originalVerdict = verdict["originalVerdict"]
if bool(originalVerdict):
    match originalVerdict:
        case "phishing":
            originalVerdictsObj.phishing += 1
            originalVerdictsObj.threat_total += 1
        case "bec":
            originalVerdictsObj.bec += 1
            originalVerdictsObj.threat_total += 1
        case "scam":
            originalVerdictsObj.scam += 1
            originalVerdictsObj.threat_total += 1
         case "malicious":
             originalVerdictsObj.malicious += 1
             originalVerdictsObj.threat_total += 1
        case "spam":
            originalVerdictsObj.spam += 1
            originalVerdictsObj.unwanted_total += 1
        case "graymail":
            originalVerdictsObj.graymail += 1
            originalVerdictsObj.unwanted_total += 1
        case "":
            noVerdictBool = True
        case _:
            originalVerdictsObj.unknown += 1


Also, I've placed print statements inside each "case" section and the interactions do indeed enter into each section and thus is doing the add 1 increment to the instance variables.  Point here is that I've verified the flow is entering into the correct section. 

Ha! No worries, so the problem isnt with the matching logic then.  I guess that the problem its not assigning the updated values of the instance variables back to the originalVerdictsObj object? Example if incrementing the phishing counter, but  not assigning the updated value back to the originalVerdictsObj object. I _think_   you can assign the updated value back to the originalVerdictsObj object. Can you try...

match originalVerdict:
    case "phishing":
        originalVerdictsObj.phishing += 1
        originalVerdictsObj = originalVerdictsObj

So from the above block you did, it would be (guessing here, i am not able to try this)

originalVerdict = verdict["originalVerdict"]
if bool(originalVerdict):
    match originalVerdict:
        case "phishing":
            originalVerdictsObj.phishing += 1
            originalVerdictsObj = originalVerdictsObj
        case "bec":
            originalVerdictsObj.bec += 1
            originalVerdictsObj = originalVerdictsObj
        case "scam":
            originalVerdictsObj.scam += 1
            originalVerdictsObj = originalVerdictsObj
        case "malicious":
            originalVerdictsObj.malicious += 1
            originalVerdictsObj = originalVerdictsObj
        case "spam":
            originalVerdictsObj.spam += 1
            originalVerdictsObj = originalVerdictsObj
        case "graymail":
            originalVerdictsObj.graymail += 1
            originalVerdictsObj = originalVerdictsObj
        case "":
            noVerdictBool = True
        case _:
            originalVerdictsObj.unknown += 1
            originalVerdictsObj = originalVerdictsObj

I think then the code will assign the updated values of the instance variables back to the originalVerdictsObj object, and the originalVerdictsObj object will keep the updated values.

Fingers crossed!

 

 

 

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

Thank you very much for thinking about this and trying but that did not work.  I'm going to upload the script but it won't have the credentials for the API to work.  Thanks again.

Marcel Zehnder
Spotlight
Spotlight

Hi, if @bigevilbeard suggestion is not working, can you post the complete code?

Woot big dawg @Marcel Zehnder in the house!

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

I need to work on my rankings

Yes.  I'll update the complete code (without API credentials).

Thank you for looking at this.  I can flip the code to use a dictionary to store the data but I'd much rather keep it with a class object.  

dalthami
Cisco Employee
Cisco Employee

I've tried to upload a zip version of the .py.  Then tried the actual .py text file.  Then renamed the .py to .txt and none of those could be uploaded here.  

Best to use GitHub imo or just post in the code block format here

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

dalthami
Cisco Employee
Cisco Employee

I finally figured it out.  It was a naming issue -- the Class and scope had nothing to do with it.  Resolved.  

@dalthami Congrats!

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

divitgupta
Level 1
Level 1

just the naming convention!

Marcel Zehnder
Spotlight
Spotlight

@dalthami : Good job!