0

may I know what is main reason for me to make decision if I should put datetime as class attribution or not? lets say if I know class Test2 is single class and definitely does not have plan to be inherited by any class

Is it correct to use as class Test2 does where it does not set any import as class attribute or ?

test1.py

import datetime

class Test1:
    datetime = datetime
    def getnow(self):
        return self.datetime.time()
    

test2.py

import datetime

datetime = datetime
class Test2:
    def getnow(self):
        return datetime.time()
Community
  • 1
  • 1
A.Lee
  • 265
  • 2
  • 9

2 Answers2

1

Neither of these implementations has any real benefit.

In test2.py, datetime = datetime is essentially a no-op. It does not change the state of the module. This is completely useless.

test1.py doesn't actually behave particularly differently, either. It just sets datetime as a class attribute, which means that it looks to the class to find datetime instead of the module. This might perform better in some very heavy load circumstances, but not enough that you should be worried about it unless you already know what you're doing.

The fact they invoke self.datetime.time(), though, suggests to me that the author's (assuming you saw someone doing this in their own code) intention was that datetime could be temporarily replaced at runtime, like this:

class FakeDatetime:
    def time(self):
        return 'from fake datetime'

t = Test1()
t.datetime = FakeDatetime()
print(t.getnow()) # Prints "from fake datetime"

To me, this looks like a misguided attempt to enable using a mock or stub for automated tests. They probably intend for it to be used something like this:

import unittest
from test1 import Test1

class TestStringMethods(unittest.TestCase):
    def test_my_method():
        mock = MyMock()
        expected_value = 'my value'
        # Set up code to make mock.time() return expected value

        t = Test1()
        t.datetime = mock
        assert t.time() == expected_value

The standard solution to mocking in Python is the unittest.mock module (or the mock package if using Python 3.2 or older). This module encourages patching to replace dependencies, rather than something manual like the code you presented:

test3.py

import datetime

class Test3:
    def getnow(self):
        return datetime.time()

test3tests.py

import unittest
from unittest import mock
from test3 import Test3

class TestStringMethods(unittest.TestCase):
    @mock.patch('test3.datetime')
    def test_my_method(datetime_mock):
        expected_value = 'my value'
        datetime_mock.time.return_value = expected_value

        t = Test3()
        assert t.time() == expected_value
        # Original datetime is restored by patch automatically when method exits
jpmc26
  • 28,463
  • 14
  • 94
  • 146
0

Based on the subject did you mean?

this

import datetime

class Test1:
    datetime = datetime
    def getnow(self):
        return self.datetime.time()

vs. this

class Test2:
import datetime

    datetime = datetime
    def getnow(self):
        return self.datetime.time()

It appears your imports should be at the top of your python file. So, in that case, Test1 is the correct way to go.

In Python, what happens when you import inside of a function?

"In general practice, it's probably not that beneficial. In fact, most Python style guides encourage programmers to place all imports at the beginning of the module file."

S. J.
  • 76
  • 8
  • Neither case serves any purpose, though. There is no need to do this. – roganjosh Jan 03 '19 at 21:31
  • I wasn't focusing on what the code was doing. I was simply looking at it from a language syntax and best practice standpoint. Where do the imports got? – S. J. Jan 03 '19 at 21:35
  • The import goes at the top of the file, and then all other re-binding of `datetime` can go. If you want `getnow` to return the current time, just `return datetime.datetime.now()` but there's no need for it to be a class attribute. – roganjosh Jan 03 '19 at 21:43
  • So you are saying that this can be accomplished with two lines of code.

    `import datetime
    return self.datetime.time()`
    – S. J. Jan 03 '19 at 21:45
  • Well, 1 after the import, depending on whether you even need your own class. The user-defined class isn't necessary at all. But I'm not sure why exactly you are asking; I'm not suggesting that you need change your answer, but are you unsure about this yourself? – roganjosh Jan 03 '19 at 21:47
  • I get your point now, the class is not needed, I think it was not a very clear question and I am making assumptions with my answer. Also the example provided could be legit if was simply a sample. Again I was focusing on answering the question, where do import statements belong. – S. J. Jan 03 '19 at 21:50
  • my question is not about where I should put import datetime. My question is about if I need to use datetime as class attribution. but still thanks for your answer – A.Lee Jan 03 '19 at 23:40
  • @A.Lee No problem, I will read more on this thread. I will read the other answers. Sorry I wasn't able to answer it for you. – S. J. Jan 04 '19 at 15:30