test initialization of object and use it [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have an class and I want to test it with the built in unittest module. In particular I want to test if I can create intances without throwing errors and if I can use them.
The problem is that the creation of this objects is quite slow, so I can create the object in the setUpClass method and reuse them.
#classmethod
def setUpClass(cls):
cls.obj = MyClass(argument)
def TestConstruction(self):
obj = MyClass(argument)
def Test1(self):
self.assertEqual(self.obj.metohd1(), 1)
the point is
I am creating 2 times the expensive object
setUp is calles before TestConstruction, so I cannot check the failure inside TestConstruction
I will be happy for example if there is a way to set TestConstruction to be executed before the other tests.

Why not test both initialization and functionality in the same test?
class MyTestCase(TestCase):
def test_complicated_object(self):
obj = MyClass(argument)
self.assertEqual(obj.method(), 1)
Alternatively, you can have one test for the case object initialization, and one test case for the other tests. This does mean you have to create the object twice, but it might be an acceptable tradeoff:
class CreationTestCase(TestCase):
def test_complicated_object(self):
obj = MyClass(argument)
class UsageTestCase(TestCase):
#classmethod
def setupClass(cls):
cls.obj = MyClass(argument)
def test_complicated_object(self):
self.assertEqual(obj.method(), 1)
Do note that if you methods mutate the object, you're going to get into trouble.
Alternatively, you can do this, but again, I wouldn't recommend it
class MyTestCase(TestCase):
_test_object = None
#classmethod
def _create_test_object(cls):
if cls._test_object is None:
cls._test_object = MyClass(argument)
return cls._test_object
def test_complicated_object(self):
obj = self._create_test_object()
self.assertEqual(obj.method(), 1)
def more_test(self):
obj = self._create_test_object()
# obj will be cached, unless creation failed

Related

How i can rewrite the repeating code from a class function, for better reusability [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 days ago.
The community is reviewing whether to reopen this question as of 5 days ago.
Improve this question
I wrote a class for which I later needed to write a specific logger.
In this particular case, standard Python logging doesn't work for me, for several reasons.
To simplify, it turned out something like this:
class Counter(object):
def __init__(self):
self.foo = 0
self.status = 'Off'
def counter_foo(self, n):
self.foo += n
def set_status(self, status):
self.status = status
def result(self):
print(f'Foo: {self.foo}')
print(self.status)
class First(object):
def __init__(self):
self.counter = Counter()
self.status = 'On'
def print_foo(self, n=1):
# This part is changing
print('foo' * n)
# This part doesn't change.
self.counter.counter_foo(n)
if self.status == 'On':
self.counter.set_status(self.status)
def end(self):
print('Bye!')
self.counter.result()
def main():
foobar = First()
foobar.print_foo(8)
foobar.end()
Part of the code in the First function changes in different projects. But the part about calling the Counter is always the same. In what ways can I redo it for easy transfer from project to project. Is a mixin suitable here, or is it better to make a decorator out of the Counter?
In a real project, in each function of the First class, there may be 3-5 calls to counter functions, but they are always the same.

Can you access attributes that were created with the init method from other methods in the class? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
When I write the __init__ method and assign attributes, can I access those attributes in other methods (functions) that I write in that class? If so, how is it done?
I've googled this but couldn't find an answer. I Haven't been able to wrap my head around this one.
Use self:
class MyClass:
def __init__(self):
self.name = 'John'
def other_method(self):
print(self.name)
other_method will print "John".
When you make a class and set an instance (like first_class = MyClass()) the def __init__(self): is run or initialised. Any variables in there, like self.name are able to be accessed from within the class and its functions, as well as when you use a class in another program. self kinda attaches that variable to that class.
Basically using Allure's example:
class MyClass:
def __init__(self):
self.name = "John"
def show_name(self):
print(self.name)
Then use MyClass's name outside of class, in a program:
firstClass = MyClass()#Initialise MyClass and its variables
print(firstClass.name)
Or:
firstClass= MyClass()
firstClass.show_name()
Both output:
'John'
(still putting up this answer for others, hope you don't mind :) )

What the purpose of creating class instance attibutes directly in the code [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Pyhon allows to create any class instance attribute just like new variable and you don't need to define them in class definition.
What's the purpose of that?
class MyClass:
def __init__(self):
pass
obj = MyClass()
obj.a = '1';
print(obj.a)
#>> 1
P.S.
found interesting example of such kind of usage
Can you use a string to instantiate a class
There dynamically created attributes used to store dynamically instatiated classes
The purpose of this is simplicity: There is no difference to accessing an instance inside or outside of a method. The object seen inside and outside of a method is completely equivalent, and by extension the same rules apply anywhere:
class MyClass:
def __init__(self):
print(self) # <__main__.MyClass object at 0x119636490>
self.b = 12 # assign to an instance
obj = MyClass()
print(obj) # <__main__.MyClass object at 0x119636490>
obj.b = 12 # # assign to an instance
Note that one can read and write attributes inside and outside methods, and these attributes are visible inside and outside of methods. In fact, Python has no concept of "inside" and "outside" of methods, aside from a few code-rewrites such as double-underscore name mangling.
This is both a result and the enabling feature to allow various inbuilt features of other languages to work without explicit support. For example, Python allows the equivalent of extension methods without extra syntax/functionality:
class MyPoint:
def __init__(self, x, y):
self.x, self.y = x, y
# Oops, forgot a repr!
def my_point_repr(self):
return f'{self.__class__.__name__}(x={self.x}, y={self.y})'
MyPoint.__repr__ = my_point_repr
print(MyPoint(1, 2)) # MyPoint(x=1, y=2)

A good practices python decorator [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I made decorators to cache the data and in particular to list the files contained in a cache file. I specify that my code works perfectly but I dont know if it is a good practice because I decorate a method of my class with my decorator "# cache.listcachedir (...)" which in reality does not call upon my method but return a result (see code above).
My decorator (in cache.py):
def listcachedir(directory):
def decorator(func):
#wraps(func)
def wrapper(self):
# Join base cache dir to directory
fdir = self.locate(directory)
if os.path.isdir(fdir):
return os.listdir(fdir)
else:
raise CacheNotFoundError()
return wrapper
return decorator
In my other py file:
class Analitics:
def __init__(self, ):
self.base_cache_dir = ".../..."
...
def locate(directory):
return os.path.join(self.base_cache_dir, directory)
...
class Analyzer(Analitics):
def __init__(self):
Analitics.__init__(self)
#cache.listcachedir('my_cache')
def getCacheList(self): return # Return any the wrapper return result
if __name__=="__main__":
ana = Analyzer()
print(ana.getCacheList()) # Works
Yes, this is bad practice because it's needlessly confusing. You can define the function more simply as:
(cache.py)
def listcachedir(analitics, directory):
# Join base cache dir to directory
fdir = analitics.locate(directory)
if os.path.isdir(fdir):
return os.listdir(fdir)
else:
raise CacheNotFoundError()
and then:
class Analyzer(Analitics):
def __init__(self):
Analitics.__init__(self)
def getCacheList(self):
return listcachedir(self, 'my_cache')
This does exactly the same thing (including separating the listcachedir implementation into its own module), but without all the confusing layers of indirection.
I find the use of a decorator misleading here.
You don't use the func argument. I expect a decorator to do something with the function (or class) it decorates. Because if it does not, what's the point of defining the function that's being decorated?
You could write your code like this:
def make_cachemethod(directory):
def cachemethod(self):
fdir = self.locate(directory)
if os.path.isdir(fdir):
return os.listdir(fdir)
else:
raise CacheNotFoundError()
return cachemethod
class Analyzer(Analitics):
getCacheList = make_cachemethod('my_cache')
# more code here

Python: should I subclass threading.Thread? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Python's threading module has two interfaces. In one you instantiate threading.Thread and pass to it the function you want to run, schematically:
class MyClass:
def __init__(self):
self.my_vars = {}
def my_func(self):
# does stuff
self.my_vars = # set result of running the function here
mc = MyClass()
t = threading.Thread(target=mc.my_func) # also, pass arguments
# set some options to t, like t.setDaemon(True)
t.start()
In the other you subclass threading.Thread and subclass the run method, schematically:
class MyClass(threading.Thread):
def __init__(self):
super(MyClass,self).__init__(*args, **kwargs)
self.my_vars = {}
def run(self):
# does stuff
self.my_vars = # set result of running the function here
t = MyThreadedClass()
t.start()
I started out using the first one, but at some point realized that I was having to write a lot of boilerplate every time I wanted to start a thread to run my_func: I kept having to remind myself the syntax to pass argments to my_func, plus I had to write multiple lines to set thread options etc etc. So I decided to move to the second style. In this way I just instantiate my class and then call .start(). Note that at this stage the difference is only in how easy it is to use these things, as my_func and run are exactly the same.
But now I'm realizing that this made my code harder to test. Before if I wanted to test my_func under so and so arguments, I just had to import the file where it is defined and then run it on some input. Or I could even do it from a jupyter notebook and play it its inputs to see its outputs. But with the second style, every time I want to do something as simple as run my_func, it comes with a thread attached.
So question: is there a way I can organize my code that it's cleaner for an application to run it on its own thread, but that has no thread when I want to call it for example from a notebook?
Make objects of your class callable:
from abc import ABCMeta, abstractmethod
import threading
class Callable:
__metaclass__ = ABCMeta
#abstractmethod
def __call__(self): raise NotImplementedError
class MyCallable(Callable):
def __init__(self, x):
self.x = x
def __call__(self):
print('x=', self.x)
# without a thread:
callable = MyCallable(7)
callable()
# on a thread:
callableThread = threading.Thread(target=callable)
callableThread.start()
callableThread.join()
You can do without the formality of using abstract base classes and abstract methods -- just make sure your class defines a __call__ method that does the work you need to do currently being done by your my_func.

Categories