I'm pretty new to python and classes so please excuse me if this is obvious!
I have a class object that I run at start up, however I would like to access that instance of the running class from another .py file
How would I go about this?
here is an example of my code:
class testclass(xml):
instanceobject = 0
def __new__(cls):
return super(testclass, cls).__new__(cls, 'xmlfile', dir1, dir2)
def __init__(self):
super(testclass, self).__init__()
testclass.instanceobject = self
print "print from class init", testclass.instanceobject
then from my other .py file, I try do the following:
from py1file import testclass
print "print from other py file", testclass.instanceobject
and I'm getting the following:
print from class init
<py1file.testclass object at 0x22F7FA80>
print from other py file
0
Basically I want to call a function from the instance of the running class but I need to pass the instance object so I'm trying to get that so I can pass the instance.
Thank you in advanced!
Related
I am trying to access to another variable that inside a function and also that is from another class, so I coded it in that way
class Helloworld:
def printHello(self):
self.hello = 'Hello World'
print (self.hello)
class Helloworld2(Helloworld):
def printHello2(self)
print(self.hello)
b = Helloworld2()
b.printHello2()
a = Helloworld()
a.printHello()
However, this gives me that error: AttributeError: 'Helloworld2' object has no attribute 'hello'. So, what would be the simplest way to access to that variable?
That's because you never call printHello(self) that declare your self.hello.
To make it work you need to do:
class Helloworld2(Helloworld):
def printHello2(self):
super().printHello()
print(self.hello)
Or move declaration of you self.hello to __init__() which would be more preferred way.
You should initialise the instance of the class via the __init__() function, this means that when it is created, these values are set.
That would make your code look like:
class Helloworld:
def __init__(self):
#sets self.hello on creation of object
self.hello = 'Hello World'
def printHello(self):
print (self.hello)
class Helloworld2(Helloworld):
def printHello2(self):
print(self.hello)
b = Helloworld2()
b.printHello2()
a = Helloworld()
a.printHello()
An alternative, with your current code is to just call printHello(), either at the top level, with b.printHello(), or within printHello2. Note that in this case, you don't actually need to use super().printHello() as you are not re-defining that function in Helloworld2, though it would be required if you did.
I have a Python class whose __init__ method raises a custom exception called WrongFileSpecified.
However, when I write a unit test, I want to assign the attributes of the instance object from a test fixture. So normally what I would be doing is reading data off a file and then working with the instance object.
But with the test, I cannot use any test files, so I basically need to hard code the data in the instance object in the setUp method of the unit test. Is there any way to get a instance created without __init__ complaining about the exception?
Sample code:
class A(object):
def __init__(self, folderPath):
#check folder path using os.isdir() otherwise raise exception
#...
self.folderPath = folderPath
#Call load record
self._load_records() #uses self.folderPath and raises exceptions as well
#Note i cannot avoid raising these exceptions, its required
class TestA(unittest.TestCase):
.......
obj = None
def setUp(self):
obj = A('fake folder path')
obj.val1 = "testparam1"
obj.param2 = "testparam2"
def test_1(self):
.....
You can create an empty object, bypassing __init__ by using __new__.
obj = obj_type.__new__(obj_type)
Note that obj_type is the appropriate type object. This is a little hacky but it works. You are reponsible for setting the object's members.
Edit: here is an example.
class Foo():
def __init__(self):
self.x = 1
self.y = 2
def say_hello(self):
print('Hello!')
r = Foo.__new__(Foo)
r.say_hello()
print(r.x)
Console output:
Hello!
Traceback (most recent call last):
File "C:\WinPython-64bit-3.3.5.7\python-
3.3.5.amd64\Scripts\projects\luc_utils\dev\test\
unit_test_serialization.py", line 29, in <module>
print(r.x)
AttributeError: 'Foo' object has no attribute 'x'
Here are two options:
Refactor the file loading out to a class method, which is the Pythonic method of providing an alternate constructor (see below); or
Provide an additional parameter to __init__ to suppress the exceptions when necessary (e.g. def __init__(self, folderPath, suppress=False), or validate=True, whichever makes more sense for your usage).
The latter is a bit awkward, in my opinion, but would mean that you don't have to refactor existing code creating A instances. The former would look like:
class A(object):
def __init__(self, ...):
"""Pass whatever is loaded from the file to __init__."""
...
#classmethod
def from_file(cls, folderPath):
"""Load the data from the file, or raise an exception."""
...
and you would replace e.g. a = A(whatever) with a = A.from_file(whatever).
There is a very useful module called mock, you can check it out later, I feel that in this case it will be too much. Instead, you should consider redesigning your class, like this, for example:
class A(object):
def __init__(self, folderPath):
self.folderPath = folderPath
def _load_records(self)
#check folder path using os.isdir() otherwise raise exception
...
#uses self.folderPath and raises exceptions as well
...
#classmethod
def load_records(cls, folderpath):
obj = cls(folderpath)
obj._load_records()
return obj
# Usage
records = A.load_records('/path/to/records')
Then you can do:
class TestA(unittest.TestCase):
.......
obj = None
def setUp(self):
self.obj = A('fake folder path')
self.obj.val1 = "testparam1"
self.obj.param2 = "testparam2"
def test_1(self):
self.assertRaises(self.obj._load_records, HorribleFailureError)
Also i highly recommend to check out pytest, it has wonderful facilities for test fixtures, including fixtures for files and folders.
class TestUM:
#classmethod
def setup_class(will):
""" Setup Class"""
will.var = "TEST"
def setup(this):
""" Setup """
print this.var
def test_number(work):
""" Method """
print work.var
def teardown(orr):
""" Teardown """
print orr.var
#classmethod
def teardown_class(nott):
""" Teardown Class """
print nott.var
Run it as
nosetests -v -s test.py
I am not a Python expert but I cannot figure out why the above code works flawlessly using nose. Every print prints "TEST". What exactly is happening here.
In instance methods, the first argument is the instance itself.
In class methods, the first argument is the class itself.
In your case, rather than name that argument self or cls (the convention), you've named it this, work, orr, and nott. But they're all getting the same argument regardless of the name of the argument.
You've successfully set the attribute var to "TEST", so they all see it correctly.
Example functions without the use of classes:
def test1(attribute):
print attribute
def test2(name):
print name
def test3(cls):
print cls
def test4(self):
print self
Calling those functions:
>>> test1('hello')
hello
>>> test2('hello')
hello
>>> test3('hello')
hello
>>> test4('hello')
hello
The name of the argument doesn't matter. All that matters is what the argument is pointing at, which is always the instance or class
In a Javascript object when I would want to initiate several functions inside an object, say myObject, I would have an init function that would call those methods to me initialized and I would simple call myObject.init(). How would I do this in python? Would the following be ok?
class Test(object):
def __init__(self, arg):
self.arg = arg
def init(self):
self.some_function()
self.some_other_function()
def some_function(self):
pass
def some_other_function(self):
pass
my_test = Test("test")
my_test.init()
Thanks for reading!
Yes. That should work fine. but I would give some other name than init(), as it would be explicit and different from default __init__
Hi I am trying to make a Logfile for my class that anything happens to be written in there...
here is how my class looks like
class MyClass:
f = open('Log.txt','a')
def __init__(self):
self.f = open('Log.txt', 'a')
self.f.write("My Program Started at "+str(datetime.datetime.now())+"\n")
def __del__(self):
self.f.write("closing the log file and terminating...")
self.f.close()
my code works, but as you see above I have two f=open('Log.txt','a')
is there any way to avoid that ?
I tried to delete one of them but it would yell at me... is there any better way to do this?
You should have only one.
The first f=... creates the file handler as a class attribute at import time, so the first time you instantiate MyClass you have the handler open, but:
MyClass() # and __del__ is called here
MyClass() # f is closed
ValueError: I/O operation on closed file
If you do it at the __init__ method creates the handler as a instance attribute and opens the file every time you instantiate MyClass(), probably this is what you want, except if you want to use the class without instantiating it.
What about something like this:
class Test:
def __init__(self): #open the file
self.f=open("log.txt", "w") #or "a"
def mywrite(self, mytext): #write the text you want
self.f.write("%s\n" % mytext)
def myclose(self): #close the file when necessary (you don't need to delete the object)
self.f.close()
myFile=Test()
myFile.mywrite("abcd")
myFile.myclose()