Python: Calling module's functions from within a class - python

I have the following code:
from suchandsuch import bot
class LaLaLa():
def __init__(self):
self.donenow = 0
print "LaLaLa() initialized."
return
def start(self):
pages = bot.cats_recursive('something')
for page in pages:
self.process_page(page)
When I try to run y = LaLaLa() and then y.start(), though, I get an error:
AttributeError: LaLaLa instance has no attribute 'cats_recursive'
This makes me suspect that Python is trying to call cats_recursive() not from suchandsuch's bot sub-module (as is defined at the beginning of the file), but rather from LaLaLa(), which of course doesn't have the cats_recursive() function. Is there a way to force a class instance to use an imported module, rather than just look inside itself?

Posters are correct that there is nothing wrong with the code you have posted.
It's the code you didn't post that is probably the problem. It is hinted at in your naming of cats_recursive. You haven't shown us that perhaps LaLaLa is defined in or imported into bot.py.
One way to replicate your error is:
# in suchandsuch/bot.py
class LaLaLa():
def __init__(self):
self.donenow = 0
print "LaLaLa() initialized."
# don't need a `return` here
def start(self):
pages = bot.cats_recursive('something')
for page in pages:
self.process_page(page)
bot = LaLaLa()
That's just one. Another is to have __init__.py in such and such something like:
bot = LaLaLa()
Like I said, the error is in your code structure.
print the id of the bot inside LaLaLa or captrue the error with pydb and I suspect you will see that bot is an instance of LaLaLa other than y (again check the id's)

You are doing fine. Most probably there is no cats_recursive() attribute in your module for real. Check syntax, check module content.

You might find the easiest way to do this would be to try to assign the cats_recursive() to the pages variable outside the class and then pass the variable to the start() function as a parameter. If this works then keep it that way, if it doesn't work then there's probably something wrong with the code elsewhere.

Related

module['test'] isn't equal to module.test?

I'm currently creating a discord bot in which I use the mechanism of modules and I want to access from the modules imported with classes integrated the informations that are set in the beginning of the class. However when i try to go into the module
https://pastebin.com/ygLAgaWB
and try to access the class into it doing the following "module.help" works but not "module['help']". Since i'm replacing the "help" with a variable like : module[var], i can' t use module.var. So how can i solve this problem ? I want to access the 'help' class in the 'module' module using a variable where 'help' is stored in.
I've tried nothing because i don't know what to do.
module = self.Modules
var = tmp[0]
class_ = module[var][var]
I expect that it return the class object.
Yes, Python isn't JavaScript, module["help"] and module.help are two different concepts. Square brackets take indices or keys, attributes are retrieved with dot notation.
If you need to access an attribute using a variable you can use
getattr(module, var)

Python unit tests: How to patch an entire class and methods

I am trying to write unittests for existing code which is poorly written and I'm finding it very hard to unit test.
def pay(self):
fraud = NewFraudCheck()
result, transaction = fraud.verify_transaction()
the test I have at the moment, I am patching the NewFraudCheck class
#patch checkout.pay.NewFraudCheck
def test_pay(self, mock_fraud_check):
mock_fraud_check.verify_transaction.assert_called()
The test is failing with a ValueError, stating that verify_transaction is not returning enough values to unpack.
I have tried adding
mock_fraud_check.verify_data.return_value = (1, 1231231)
however this doesn't seemt o have any effect.
There are a few issues I'll point out, but the question is missing a few details so hopefully I can address them all in one shot:
Your syntax here is wrong: #patch checkout.pay.NewFraudCheck. It should be #patch('checkout.pay.NewFraudCheck')
There is a missing class somewhere that has the function pay(self) on it. That class lives inside a module somewhere which is important to properly mock NewFraudCheck. I'll refer to that missing module as other.
NewFraudCheck needs to be patched at the point where it's looked up. That means, in the mystery module other where there's a class that has pay(self) defined in it, there's presumably an import of from pay import NewFraudCheck. That is where NewFraudCheck is looked up, so your patch will need to look like this: #patch('checkout.other.NewFraudCheck). More info here: http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch
You need to assign/use the return value of your patch, not access verify_transaction directly off of the mock. For instance, it should read like this: mock_fraud_check.return_value.verify_transaction.return_value = (1, 1231231). Notice the inclusion of return_value.
The final test I came up with looked like this and passed:
#mock.patch('checkout.other.NewFraudCheck')
def test_pay(self, mock_fraud_check):
# This is the class that lives in mystery module, 'checkout.other' and calls pay()
other_class = SomeOtherClass()
mock_fraud_check.return_value.verify_transaction.return_value = (1, 1231231)
other_class.pay()
mock_fraud_check.return_value.verify_transaction.assert_called()

How to change class object parameters from another module (python)

So I've searched around and couldn't find an answer. I'm looking to change parameters from an object created in my main file, in a module. For example, I'm testing this with a simple piece of code here:
-this is my main file, from which i create the objects and define some properties
import class_test_2
class dog():
name=''
spots=0
def add_spots(self):
self.spots+=1
def main():
fido=dog()
fido.name='Fido'
print('Fido\'s spots: ',fido.spots)
fido.add_spots()
print('Fido\'s spots: ',fido.spots)
class_test_2.class_test()
print('Fido\'s spots: ',fido.spots)
if __name__=='__main__':
main()
-this is the module, from which I want to use functions to change the attributes in the main file
from class_test_1 import dog
def class_test():
fido.add_spots()
-So my question is how can I do this/why doesn't this piece of code above work?
Running the main function on its own shows fido's spots increasing by 1 each time its printed. Running the code calling the module however gives a NameError so my module isn't recognising the class exists even though I've managed to import it. Thanks in advance for any help.
Your variable "fido" is only defined within your "main" function. You must provide your "class_test" function with the variable.
For example:
class_test_2.class_test(fido)
Then your class_test function gets an argument. You can choose the name freely. I used the_dog in the example:
def class_test(the_dog):
the_dog.add_spots()
In this case the_dog points to the same instance of your dog class as fido.

Python my Class throws TypeError

here is my code.
import fileinput, random
from os import system as sys
from sys import exit
class crazy8(object):
question = raw_input("please enter a yes or no question \n")
def fortune(self, filex, current):
current = r"./"
fortunes = list(fileinput.input(filex))
sys("cd", current)
print random.choice(fortunes)
crazy8.fortune(r"./crazy8")
exit(0)
When I run the program, I enter a question (I know that the program does not care what is entered). I think I did something wrong with the class. I know it works fine when there is no class: statement, but I need the class there (after I am done, I am going to use this as a module).
After the question, I get
TypeError: unbound method fortune() must be called with crazy8 instance as first argument (got str instance instead)
(I did not add any error checking yet. I will try to add try and catch/raise for if the file ./crazy8 does not exist. Also, I am later going to add a file that will automatically sys("touch ./crazy8") (on Mac/linux) and, after I find out how to create a file on Windows, I will add that.
You need to create and instance or object of the class(same thing).
x = crazy8()
x.fortuner(r,"./crazy8")
It's also considered common practice to have your classes start with capital letters and instances with lowercase.
class Crazy8
crazy8 = Crazy8()
Hope this helps
Either you should create an instance of the class and call its method, or you should make the method static.
Please refer to:
Static methods in Python

How to make wxPython class browser

How do I implement a class browser in wxPython? Should I scan the whole code, or there is a function for this in wxPython?
Your question isn't entirely clear about what you want, but I'll make some assumptions and show you how to do one of the possible interpretations of what you're asking.
I'll assume you have a string with the contents of a Python script, or a fragment from your cut-and-paste repository, or whatever, and you just want to know the top-level classes defined in that string of source code.
You probably don't want to execute that code. For one thing, who knows what arbitrary strange code can do to your environment? For another, if you're building a class browser, you probably want it to work on code that's depends on other code you may not have access to, so you can't execute it.
So, you want to parse it. The easiest way to do that is to get Python to do it for you, using the ast module:
import ast
with open('mymodule.py') as f:
mycode = f.read()
myast = ast.parse(mycode)
for thing in myast.body:
if isinstance(thing, ast.ClassDef):
print('class {}({})'.format(thing.name,
', '.join(base.id for base in thing.bases)))
for subthing in thing.body:
if isinstance(subthing, ast.FunctionDef):
print(' def {}'.format(name))
When I run this against, say, the ast.py from Python 3.3's stdlib, I get this:
class NodeVisitor(object)
def visit
def generic_visit
class NodeTransformer(NodeVisitor)
def generic_visit
If that's not what you wanted, you'll have to explain what you do want. If, for example, you want all class definitions, even local ones within functions and methods… well, the names of those two classes just dumped out above should help.

Categories