Python3 - How do I import a class from another file
DL Neil
PythonList at DancesWithMice.info
Mon Dec 9 17:59:31 EST 2019
It might be becoming 'long', but this discussion contains much of profit
to many people!
Us 'silver surfers' do need to periodically question those beliefs we
hold as 'tenets' of ComSc. Amongst them is RAM (or "core"!)
conservation. It remains a virtue somewhat, but at the same time,
storage costs are considerably cheaper than they were four decades ago,
whereas the relative-cost of your time (to think about such things) has
increased!
That said, many of our more youthful (and in their own words "better in
every way", harrumph!) colleagues should also review their own beliefs
from time-to-time, eg working with IoT devices certainly requires a more
conservative and considerate approach to resources!
(and in such applications, we tend to enjoy significant advantage
because we've 'been there, done that'!)
Similarly, it is a serious fallacy to attempt to directly 'translate' a
'command' from one language into an 'equivalent' in another/a new
language. Whilst the syntax may appear similar, such superficiality
doesn't allow for subtleties of meaning! In the same way, if you ask one
person to translate the English word "preserve" into German, and then
another person to translate that German word into English, what are the
chances that the 'answer' will be "preserve"? Given that "preserve"
could mean a jam/jelly/conserve (noun) or (verb) 'maintain the meaning',
with a similar range of synonyms (etc) on the German side; the word
"preserve" is unlikely to be preserved!
(with all due apologies for such terrible humor and word-play!)
On 9/12/19 11:32 PM, Terry Reedy wrote:
> On 12/9/2019 2:36 AM, R.Wieser wrote:
>> Terry,
>>> Standard for in-file test is
>> [snip]
>>
>> Any reason to put the testcode in a procedure instead of just have it
>> directly follow the "if __name__ == '__main__' " test ?
>
> One can, for instance, interactively do
>
> >>> import mod
> >>> mod.test()
...
I went through this cycle of thinking, first using if __name__... to
'hide' testing, then adding test functions within the module, and now
keep test code quite separate from 'the real thing'.
In fact, PyTest (for example) will auto-magically look for test-code in
sub-directories of the project directory, eg "projectNM/tests". So, for
every (Python) file in my projectDIR, you should be able to find at
least one corresponding Python test-file in the tests sub-dir!
This fits with your philosophy of keeping (imported) modules small,
perhaps to the point of separating each class into its own module - if
'efficiency' is the goal, why would you want to include test-code within
a 'production system'?
On which point, if we had a class Person(); and then decided that in
certain cases we wanted specific methods that didn't apply to every
(type of) Person, we would likely create a sub-class, eg class Man(
Person ); - although some might dispute the accuracy of such an "is a"
relationship...
That being the case, were you to put the Man class' code into (say) a
module called "man.py" and Person()'s code into "person.py", then a
point made earlier is that you can't merely import man.py;! You must
also ensure that person.py is imported, somewhere along the line. Thus,
because it names (and requires the logic of) the super-class, the
sub-class cannot be imported 'alone'. (regardless of saving-space
objectives, etc)
Expanding on 'names' and del(): the first point is that there is seldom
much to be gained by using del(), ie becoming your own 'garbage
collector'. That said, there are some very specific times when it
becomes absolutely necessary (otherwise the Python 'gods' would not have
given us the functionality!). Once again, RAM is (relatively) plentiful,
and when you need to replicate many multiples of an object, it is likely
within a loop and therefore the same instanceNM is being 're-used' and
the garbage-collector takes care of 'recycling' the storage space
auto-magically.
Regarding 'names', yes some languages are "strongly typed" and (mostly)
for that reason include an indicator of "type" within the name. Python
enables you to play fast-and-loose, eg
>>> x = 1
>>> x = "abc"
>>> x = 2.3
>>> x = [ 1, 2, 3 ]
>>> x = ( 1, 2, 3 )
>>> x = 1, 2, 3
constitutes a perfectly legal program (where "legal" != "useful").
There again, there are times when values are processed into a different
data structure, eg we start with a list of values, but only want to use
unique values/process each representative-member once.
A Python-list will handle the former (wow, that's a bit of 'rocket
science'!?) whereas a Python-set will only contain unique values. So,
rather than using a somewhat-bland varNM such as "letters", I would
choose to be more explicit:
>>> letters_list = [ "a", "b", "a", "c", "a", "d", "a" ]
>>> len( letters_list )
7
>>> letters_set = set( letters_list )
>>> len( letters_set )
4
>>> letters_set
{'b', 'a', 'd', 'c'}
There is no question whether "letters" is a list, or a set, (or ...),
because of the explicit varNMs.
However, there are many people who dislike such an approach. Sadly, I'm
not smart-enough to run with that crowd...
Remember that the naming conventions (mentioned elsewhere) also give you
a hint as to type. Relevant here:
class Person(): ... # Person is a classNM = title-case
class Man( Person ): ... # as is Man
david = Man( etc ) # david is an instance and NOT a class (?classy)
rudy = Man( etc ) #rudy probably does have class, in this instance
del( david ) # is quite different to/separate from rudy
del( Person ) # and we know this is a class cf an instance
However, I'd question:
del( rudy )
because that might risk a tear in your space-time continuum... (!?)
--
Regards =dn
More information about the Python-list
mailing list