Print function prints twice a field from a class - python

I am using the print function to print a field from a class from another python module and it prints the field twice.
I have two modules:
main.py:
from statics import RiskyCars
class Car:
def __init__(self, name):
self.name = name
# init
RiskyCars()
print(RiskyCars.risky_cars[0].name)
statics.py:
class RiskyCars:
#staticmethod
def __init__():
from main import Car
RiskyCars.risky_cars = []
RiskyCars.risky_cars.append(Car("car1"))
When I run main.py it print twice:
C:\Python27\python.exe C:/Users/myuser/PycharmProjects/Project1/main.py
car1
car1
But if I put breakpoint before the print function:
# main.py
# init
RiskyCars() <--- break point
and then run manually from the terminal:
print(RiskyCars.risky_cars[0].name)
it prints only one time.
Why it happens ?

Python renames the primary script you run main for you as __main__. What happens is that you run main (called __main__) which runs RiskyCars.__init__ which in turn imports main (called main). Hence the script main runs twice.
The solution is to rewrite main.py to be
from statics import RiskyCars
if __name__ == '__main__': # only execute if run as main script
# init
risky_car_1 = RiskyCars() # lets at least pretend this is sensible
print(RiskyCars.risky_cars[0].name)
statics.py to
from cars import Car
class RiskyCars:
risky_cars = []
def __init__(self):
RiskyCars.risky_cars.append(Car("car1"))
and make a new file called cars.py
class Car:
def __init__(self, name):
self.name = name

Related

How do I access the variable inside a class method from another python file?

I have two python files main.py and conftest.py. I want to access a variable of a method of the class Test declared in main.py from a function declared in conftest.py.
I have tried a bit, but I know it's wrong as I get a syntax error in the first place. Is there any way to do this?
main.py
class Test():
def test_setup(self):
#make new directory for downloads
new_dir = r"D:\Selenium\Insights\timestamp}".format(timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
# print(new_dir)
if not os.path.exists(new_dir):
os.makedirs(new_dir)
saved_dir=new_dir
conftest.py
from main import Test
def newfunc():
dir=Test.test_setup()
print(dir.saved_dir)
There are some errors in your code, but essentially, to access to the variable saved_dir you have to define it as an attribute of the class Test, and after that instantiate an object of that class.
In your code saved_dir is a local variable of the method test_setup so is not visible outside of that context.
I show you the 2 possible correct files:
File main.py
from datetime import datetime
import os
class Test():
def __init__(self):
self.new_dir = ""
self.saved_dir = ""
def test_setup(self):
#make new directory for downloads
#new_dir = r"D:\Selenium\Insights\timestamp}".format(timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
self.new_dir = "/home/frank/Selenium/Insights/timestamp/" + timestamp
# print(new_dir)
if not os.path.exists(self.new_dir):
os.makedirs(self.new_dir)
self.saved_dir = self.new_dir
def get_saved_dir(self):
return self.saved_dir
Pay attention: don't use directly the previous code because in main.py I have adjusted the value of new_dir according to my environment (see /home/frank/Selenium/Insights/timestamp/ instead of your D:\Selenium\Insights\timestamp).
File conftest.py:
from main import Test
def newfunc():
test_class = Test()
test_class.test_setup()
print(test_class.get_saved_dir())
newfunc()
If you want to access to the attribute saved_dir directly without the use of method get_saved_dir() (not very object oriented) the file conftest.py becomes:
from main import Test
def newfunc():
test_class = Test()
test_class.test_setup()
# access directly to attribute saved_dir (not properly Object Oriented)
print(test_class.saved_dir)
newfunc()
Variable must be declared as belonging to the class
class Test():
def __init__(self):
self.new_dir = ""
self.saved_dir = ""
def test_setup(self):
#make new directory for downloads
self.new_dir = r"D:\Selenium\Insights\timestamp}".format(timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
# print(self.new_dir)
if not os.path.exists(self.new_dir):
os.makedirs(self.new_dir)
self.saved_dir=self.new_dir
Then calling it
def newfunc():
dir=Test().test_setup()
print(dir.saved_dir)

How to Import Class From Inside the Main function of another file?

I want to import a class defined within the main() function of another file to my current script.
Here is the code:
File A.py
def main():
class Aclass()
def foo(self):
return x
I want to include the above Aclass in my current file but when I import A.py I get the error:
no attribute 'Aclass"
Because you're declaring the class inside a function, so you will be able to import main() but not Aclass(). Just move your class definition outside the main function and that will do the trick
I don't know what do you want by that but You can return that class when you run that function.
For example:
def main():
class Aclass():
def __init__(self):
pass
return Aclass
f = main()
y = f()
Your class's object now is y variable
Your way in writing code is not correct but every one has thoughts or ideas that they want to do it.

Parent class init is executing during inheritence

One basic question in OOP.
test.py file content:
class test(object):
def __init__(self):
print 'INIT of test class'
obj = test()
Then I opened another file.
I just inherited from the above test class:
from test import test
class test1(test):
def __init__(self):
pass
So when I run this second file, the __init__() from the parent class is executed (the INIT got printed).
I read that I can avoid it by using
if __name__ == '__main__':
# ...
I can overcome this, but my question is why the parent class's init is executing as I am just importing this class only in my second file. Why is the object creation code executed?
Importing a module executes all module-level statements, including obj=test().
To avoid this, make an instance only when run as the main program, not when imported:
class test(object):
def __init__(self):
print 'INIT of test class'
if __name__ == '__main__':
obj=test()
The problem is not the inheritance but the import. In your case you execute obj=test() when importing:
from test import test
When you import test, its name __name__ is test.
But when you run your program on the command line as main program with python test.py, its name is __main__. So, in the import case, you skip obj=test()if you use:
if __name__ == '__main__':
obj=test()

How Pylint determine Instance has variable or not

I have written simple file and run Pylint on this code code. Does anyone have idea How Pylint determine that Class sample does not have second variable.
Purpose: I would like to write simple script which will read sample
file(python code) and check which instance variable is accessed and
set by Instance. Ex if I write in main time.initial_time than my script able to detect that initial_time has been accessed by time Instance. it will be run at the run time. I mean, it will be part of existing flow
Real Purpose
To filter out unused member variable of class which is used thousands places and more than 100 variable
Sample file
"""testing pylint code"""
#!/usr/bin/env py
class Sample(object):
"""create sample class"""
def __init__(self):
"""seting variable"""
self.intial_time = 0
def main():
"""main functionality"""
time = Sample()
print time.second
if __name__ == " __main__":
main()
Pylint Error:
************* Module class_instance
R: 3, 0: Too few public methods (0/2) (too-few-public-methods)
E: 12,10: Instance of 'Sample' has no 'second' member (no-member)

Dynamic loading of classes

My goal is to load dynamically my different subclasses and execute them. To call my script, I am using this:
python Plugin.py Nmap execute google.com
Or
python Plugin.py Dig execute google.com
Here it's the code
Parent Class: Plugin.py
class Plugin(object)
def __init__(self):
self.sName = ''
def execPlugin(self):
return 'something'
def main():
# get the name of the plugin
sPlugin = sys.argv[1]
# create the object
mMod = __import__(sPlugin, fromlist=[sPlugin])
mInstance = getattr(mMod, sPlugin)
oPlugin = mInstance()
print oPlugin
print type(oPlugin)
if (sys.argv[2] == 'execute'):
# then execute it
return oPlugin.execPlugin(sys.argv[3])
if __name__ == '__main__':
main()
Sub Class located in Nmap/Nmap.py
class Nmap(Plugin):
def __init__(self):
self.sName = 'Nmap'
def execPlugin(self):
return 'something else'
Sub Class located in Dig/Dig.py
class Dig(Plugin):
def __init__(self):
self.sName = 'Dig'
def execPlugin(self):
return 'yeahhh'
My problem is located in
oPlugin = mInstance()
With the following error
TypeError: 'module' object is not callable
I tried so many things but nothing worked. How can I solve my problem?
You have a structure like:
Plugin.py
/Nmap
__init__.py
Nmap.py
# class Nmap(Plugin): ...
In Plugin.py, when you do mMod = __import__(sPlugin, fromlist=[sPlugin]) where sPlugin == 'Nmap', this makes mMod refer to the directory /Nmap, not the file Nmap.py (note that both files and directories can be modules in Python). Hence mInstance = getattr(mMod, sPlugin) makes mInstance the file Nmap.py rather than the class Nmap.
There are two ways to fix this, either:
Use the __init__.py in /Nmap to bring the class "up" one level, i.e. include from Nmap import Nmap; or
Add an extra level of getattr into Plugin.py.
Additionally, you should follow the style guide's naming conventions, which might have helped you track the issue down faster.

Categories