How do I use a class method in a separate program? - python

I have a quite a bit of confusion on how to use classes. I understand what they are, and why they should be used, just not how. For example, we're given a pre-made class (I'll call it class Class_1(object) to keep things simple) with a few functions (methods, right?) and variables in it.
class Class_1(object):
var_1= [a,b,c]
var_2= [x,y,z]
var_3= {n:[o,p],g:[h,i]}
def method_1(self):
'''here's a method'''
(As a side note, the Class_1(object) does have the __init__(self): method already done.)
Now, in a separate program, I've imported the file that contains that class at the top of the program, but how do I use methods or variables from the class? For example, if I want to check a user input against a value in var_1, how would I do that?
I've gotten better with functions in general, but calling on classes and methods is as clear as mud.
Edit: Realized I said "methods" instead of "variables" when I actually need both.

To use the class, you need to create an class instance from the separate file:
import filename1
class1 = filename1.Class_1()
With the instance, you can then access the member variables:
value1 = class1.method_1

Related

Init in classes - is the first argument a stand in for the instance?

I have been trying to fully understand this for a while now, and practically speaking I think I understand what happens but I can't seem to find anywhere that confirms wether I understood it correctly:
class test(object):
def __init__(self, this):
self.something = this
example = test("writing")
My question is: In the above example, is it correct that self is simply a stand-in for the instance I am creating? Meaning that when i create an instance and assign it to "example", then "example is put in place of self and behind the scenes does something resembling this:
class test(object):
def __init__(example, this):
example.something = this
example = test("writing")
Furthermore, does that also mean that as long as I am still working with this on a class basis (say in tandem with another class) I should still be using self.something, while I should be using example.something if I am working with it on an instance level?
I hope that made somewhat sense, im still trying to wrap my head properly around all of it, so let me know if I need to try and rephrase it.
For reference sake, should someone else end up asking the same, this reply: Python __init__ and self what do they do? almost did the trick for me, and only really left me a bit in doubt about the above questions.
This is correct. self is the instance of the class (i.e. the object) and you use it inside the class code (inside it's methods).
While the first argument can be named something else (example in your second code), the convention is that we always use self or the code might be highly confusing for other programmers. But you got the gist right by doing that, the example variable in the class (i.e. the self in your first code) and the example variable outside of the class is basically the same thing.
By the way, I'd also avoid the following two things:
having a class name that starts with a small leter case,
using a variable name this (since a variable named this does in some other languages essentially what self does in Python).
In Python, variables do not "contain" objects, they refer to them. So:
class test(object):
def __init__(self, this):
self.something = this
example = test("writing")
In this case example is a reference to the new object, but so is self. It is perfectly legal, and common, to have multiple references to the same object.
If you did:
another = example
this would not create a new object but have another reference to the same object. another, example (and self) would be references to the same single object.
You can test this by looking at the object's unique identifier, using id(). Add:
another = example
print id(another)
print id(example)
you will find that their id's are the same.

Python: How to get all of the local variables defined in another module

Is there a way to get a reference to the local variables defined in a different module?
for example, I have two files: framework.py and user_code.py:
framework.py:
from kivy.app import App
class BASE_A:
pass
class MyApp(App):
def on_start(self):
'''Here I'd like to get a reference to sub-classes of BASE_A and
instantiated objects of these sub-classes, defined in the file
"user_code.py" such as a1, a2, as well as the class A itself,
without explicitly passing them to MyApp's instance.
'''
user_code.py:
from framework import MyApp
class A(BASE_A):
pass
app = MyApp()
a1 = A()
a2 = A()
app.run()
What I'd like to do is to somehow get a reference to the objects a1 and a2, as well as the class A, that were all defined in user_code.py. I'd like to use them in the method on_start, which is invoked in app.run().
Is it possible, for example, to get a reference to the scope in which the MyApp object was defined (user_code.py)?
Some background for anyone who's interested:
I know it's a bit of an odd question, but the reason is:
I'm writing a python framework for creating custom-made GUI control programs for self-made instruments, based on Arduino. It's called Instrumentino (sitting in GitHub) and I'm currently developing version 2.
For people to use the framework, they need to define a system description file (user_code.py in the example) where they declare what parts they're using in their system (python objects), as well as what type of actions the system should perform (python classes).
What I'm trying to achieve is to automatically identify these objects and classes in MyApp's on_start without asking the user to explicitly pass these objects and classes, in order to make the user code cleaner. Meaning to avoid code such as:
app.add_object(a1)
app.add_object(a2)
app.add_class(A)
New-style classes in Python have a method named __subclasses__ which returns a list of all direct subclasses that have been defined so far. You can use that to get a hold of the A class in your example, just call BASE_A.__subclasses__() (if you're using Python 2, you'll also need to change BASE_A to inherit from object). See this question and its answers for more details (especially the functions to recursively get all subclasses).
As for getting access to the instances, for that you probably should add some code to the base class, perhaps saving the instances created by __new__ into some kind of data structure (e.g. a weakset). See this question and its answers for more on that part. Actually, now that I think about it, if you put your instances into a centralized data structure somewhere (e.g. not in an attribute of each subclass), you might not need the function to search for the classes, since you can just inspect the type of the instances and find the subclasses that are being used.
Your question is a bit illogical.
Since Python interprets the code sequentially: b is not defined before a initialization.
If you can set b before a then:
b = None # global variable
class A():
global b
def __init__(self):
'''Here I'd like to get a reference to b (of type B) without passing it as an argument'''
class B_BASE():
pass
class B(B_BASE):
def __init__(self):
pass
if __name__ == '__main__':
b = B()
a = A()
I wouldn't recommend doing this because I find that this isn't clean. Since you have a dependency on b in a you should pass it as a parameter to the A class

Re-initializing parent of a class

I have become stuck on a problem with a class that I am writing where I need to be able to reinitialize the parents of that class after having created an instance of the class. The problem is that the parent class has a read and a write mode that is determined by passing a string to the init function. I want to be able to switch between these modes without destroying the object and re-initialising. Here is an example of my problem:
from parent import Parent
class Child(Parent):
def __init__(mode="w"):
super.__init__(mode=mode)
def switch_mode():
# need to change the mode called in the super function here somehow
The idea is to extend a class that I have imported from a module to offer extended functionality. The problem is I still need to be able to access the original class methods from the new extended object. This has all worked smoothly so far with me simply adding and overwriting methods as needed. As far as I can see the alternative is to use composition rather than inheritance so that the object I want to extend is created as a member of the new class. The problem with this is this requires me to make methods for accessing each of the object's methods
ie. lots of this sort of thing:
def read_frames(self):
return self.memberObject.read_frames()
def seek(self):
return self.memberObject.seek()
which doesn't seem all that fantastic and comes with the problem that if any new methods are added to the base class in the future I have to create new methods manually in order to access them, but is perhaps the only option?
Thanks in advance for any help!
This should work. super is a function.
super(Child, self).__init__(mode=mode)

Why do we use #staticmethod?

I just can't see why do we need to use #staticmethod. Let's start with an exmaple.
class test1:
def __init__(self,value):
self.value=value
#staticmethod
def static_add_one(value):
return value+1
#property
def new_val(self):
self.value=self.static_add_one(self.value)
return self.value
a=test1(3)
print(a.new_val) ## >>> 4
class test2:
def __init__(self,value):
self.value=value
def static_add_one(self,value):
return value+1
#property
def new_val(self):
self.value=self.static_add_one(self.value)
return self.value
b=test2(3)
print(b.new_val) ## >>> 4
In the example above, the method, static_add_one , in the two classes do not require the instance of the class(self) in calculation.
The method static_add_one in the class test1 is decorated by #staticmethod and work properly.
But at the same time, the method static_add_one in the class test2 which has no #staticmethod decoration also works properly by using a trick that provides a self in the argument but doesn't use it at all.
So what is the benefit of using #staticmethod? Does it improve the performance? Or is it just due to the zen of python which states that "Explicit is better than implicit"?
The reason to use staticmethod is if you have something that could be written as a standalone function (not part of any class), but you want to keep it within the class because it's somehow semantically related to the class. (For instance, it could be a function that doesn't require any information from the class, but whose behavior is specific to the class, so that subclasses might want to override it.) In many cases, it could make just as much sense to write something as a standalone function instead of a staticmethod.
Your example isn't really the same. A key difference is that, even though you don't use self, you still need an instance to call static_add_one --- you can't call it directly on the class with test2.static_add_one(1). So there is a genuine difference in behavior there. The most serious "rival" to a staticmethod isn't a regular method that ignores self, but a standalone function.
Today I suddenly find a benefit of using #staticmethod.
If you created a staticmethod within a class, you don't need to create an instance of the class before using the staticmethod.
For example,
class File1:
def __init__(self, path):
out=self.parse(path)
def parse(self, path):
..parsing works..
return x
class File2:
def __init__(self, path):
out=self.parse(path)
#staticmethod
def parse(path):
..parsing works..
return x
if __name__=='__main__':
path='abc.txt'
File1.parse(path) #TypeError: unbound method parse() ....
File2.parse(path) #Goal!!!!!!!!!!!!!!!!!!!!
Since the method parse is strongly related to the classes File1 and File2, it is more natural to put it inside the class. However, sometimes this parse method may also be used in other classes under some circumstances. If you want to do so using File1, you must create an instance of File1 before calling the method parse. While using staticmethod in the class File2, you may directly call the method by using the syntax File2.parse.
This makes your works more convenient and natural.
I will add something other answers didn't mention. It's not only a matter of modularity, of putting something next to other logically related parts. It's also that the method could be non-static at other point of the hierarchy (i.e. in a subclass or superclass) and thus participate in polymorphism (type based dispatching). So if you put that function outside the class you will be precluding subclasses from effectively overriding it. Now, say you realize you don't need self in function C.f of class C, you have three two options:
Put it outside the class. But we just decided against this.
Do nothing new: while unused, still keep the self parameter.
Declare you are not using the self parameter, while still letting other C methods to call f as self.f, which is required if you wish to keep open the possibility of further overrides of f that do depend on some instance state.
Option 2 demands less conceptual baggage (you already have to know about self and methods-as-bound-functions, because it's the more general case). But you still may prefer to be explicit about self not being using (and the interpreter could even reward you with some optimization, not having to partially apply a function to self). In that case, you pick option 3 and add #staticmethod on top of your function.
Use #staticmethod for methods that don't need to operate on a specific object, but that you still want located in the scope of the class (as opposed to module scope).
Your example in test2.static_add_one wastes its time passing an unused self parameter, but otherwise works the same as test1.static_add_one. Note that this extraneous parameter can't be optimized away.
One example I can think of is in a Django project I have, where a model class represents a database table, and an object of that class represents a record. There are some functions used by the class that are stand-alone and do not need an object to operate on, for example a function that converts a title into a "slug", which is a representation of the title that follows the character set limits imposed by URL syntax. The function that converts a title to a slug is declared as a staticmethod precisely to strongly associate it with the class that uses it.

how to override class, or undeclare class or redeclare a Class in python?

is there any possible to override class, or undeclare class or redeclare a Class in python?
Yes, just declare it again:
class Foo(object): x = 1
class Foo(object): x = 2
The above code will not raise any error, and the name Foo will refer to the second class declared. Note however, that the class declared by the first declaration will still exist if anything refers to it, e.g. an instance, or a derived class.
This means that existing instances will not change class when you declare a new class with the same name, and existing subclasses will not magically inherit from the new class.
Probably the simplest method to deal with subclasses is to also re-declare them, so they inherit from the "renewed" base class. An alternative would be to mess with their __bases__ property, although I can't tell you if that would have unexpected results (there will almost certainly be some corner cases where this would not work).
As to existing instances, it is possible to re-assign their __class__ property with a new class. This does present two issues - first you have to find them (see this question: Printing all instances of a class), and second of all, items stored in instance __dict__ or __slots__ properties will still be there in those instances. If that is not something that should happen with your new class definition, you will have to write appropriate code to handle that as part of the transformation.
IN summary, it's unlikely to be worth it except in quite simple cases. If you need complete uptime for a running system, you might be better using a replication-based approach to achieve code changes.
Update: If this is the kind of thing you know you're going to do, another solution would be to use the strategy pattern.
Undeclare a class using del className as usual.

Categories

Resources