Python 2.7: Issues When Importing a Class - class

I have been searching high and low for an answer and cannot seem to find one. I am running into a fundamental issue when attempting to import a class from another file. I am relatively new to Python and OOP in general, so forgive me if my query is rudimentary.
The Issue: I want to import a CHILD class into a PARENT class. Simple enough, but when I import the class it immediately executes.
The Question: How do I import a class so it can be referenced globally in my parent class?
Here is a basic example of the PARENT class:
from child import CHILD
class PARENT:
def _init_(self):
print "START PARENT CLASS"
def goTo(self,enter):
if enter == "1":
c.childScreen()
else:
self.parentScreen(self):
def parentScreen(self):
enter = raw_input("ENTER [1] to go to CHILD class:")
self.goTo(enter)
p = PARENT()
c = CHILD()
Okay, so to my beginner eyes this conceptually should work. I imported the class CHILD and created a reference to it "c = CHILD". This concept works when both class's are in the same file but not when they are in two different files. Why?
Instead of importing CHILD from child and storing it as a reference it instead executes immediately and does not initiate the PARENT class. Why doesn't this work?
I have seen people reference the whole 'name' == 'main' but I don't really know how to implement that and I feel as if there is an easier way.
Any help would be appreciated. Thank you!

You are importing the CHILD class properly, but you are calling it from outside your PARENT class. The PARENT class thinks that the variable c is a local variable to the function goTo. You could use a global variable c, but anyone would tell you that that is a big no no.
To answer your other question you probably have some code that executes in CHILD. If you only want this code to run when you run the file in which the CHILD class then put it after a
if __name__ == '__main__':
This only allows the code preceding it to run if executed directly and it will not run if you import the class. see examples below.
You can just create an instance variable of the CHILD class in your __init__ and use it in the rest of your PARENT class.
class PARENT(object):
def _init_(self):
print "START PARENT CLASS"
self.c = CHILD() # create instance of CHILD
def goTo(self,enter):
if enter == "1":
self.c.childScreen() # then you can access CHILD class like this
else:
self.parentScreen(self):
def parentScreen(self):
enter = raw_input("ENTER [1] to go to CHILD class:")
self.goTo(enter)
if __name__ == '__main__':
p = PARENT()
or you can actaully inherit CHILD into PARENT:
class PARENT(CHILD):
def _init_(self):
print "START PARENT CLASS"
def goTo(self,enter):
if enter == "1":
# now you can access the CHILD functions as if the we were coded in the
# PARENT class
self.childScreen()
else:
self.parentScreen(self):
def parentScreen(self):
enter = raw_input("ENTER [1] to go to CHILD class:")
self.goTo(enter)
if __name__ == '__main__':
p = PARENT()

Related

Python C API - How to inherit from your own python class?

The newtypes tutorial shows you how to inherit from a base python class. Can you inherit from your own python class? Something like this?
PyObject *mod = PyImport_AddModule("foomod");
PyObject *o = PyObject_GetAttrString(mod, "BaseClass");
PyTypeObject *t = o->ob_type;
FooType.tp_base = t;
if (PyType_Ready(&FooType ) < 0) return NULL;
though you need to define your struct with the base class as the first member per the documentation so it sounds like this is not possible? ie how would I setup the Foo struct?
typedef struct {
PyListObject list;
int state;
} SubListObject;
What I'm really trying to do is subclass _UnixSelectorEventLoop and it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
I think you're basically right on your assessment:
it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
You can't define a class that inherits from a Python class because it'd need to start with a C struct of basically arbitrary size.
There's a couple of other options that you might like to consider:
You could create a class the manual way by calling PyType_Type. See this useful answer on a question about multiple inheritance which is another sort of inheritance that the C API struggles with. This probably limits you too much, since you can't have C attributes, but you can have C functions.
You could do "inheritance by composition" - i.e. have you _UnixSelectorEventLoop as part of the object, then forward __getattr__ and __setattr__ to it in the event of unknown attributes. It's probably easier to see what I mean with Python code (which is simply but tediously transformed into C API code)
class YourClass:
def __init__(self,...):
self.state = 0
self._usel = _UnixSelectorEventLoop()
def __getattr__(self, name):
return getattr(self._usel, 'name')
def __setattr__(self, name, value):
if name in self.__dict__:
object.__setattr__(self, name, value)
else:
setattr(self._usel, name, value)
# maybe __hasattr__ and __delattr__ too?
I'm hoping to avoid having to write this C API code myself, but the slots are tp_getattro and tp_setattro. Note that __getattr__ will need to be more comprehensive in the C version, since it acts closer to the __getattribute__ in Python. The flipside is that isinstance and issubclass will fail, which may or may not be an issue for you.

Text widget is not accessible to a helper function in Python3x tkinter

I am learning python tkiner from a reference book. The examples are coded in plain style, i.e., not in class format. I want to learn coding in classes because I think it helps manage long codes.
I am trying to make the text widget (named textPad) accessible to a helper function inside a class called TextEditor. The job of the helper function is to select all the text which I type. However, as soon as I run the script, I get global error that the textPad is not defined. Even when I add self. to textPad, i.e., self.textPad, I get an attribute error that Class object has no attribute textPad. The code is part of an excercise to make a full functional text editor. Below, I provide the core code which generates the error. What is the wrong with this code?
Could you please clarify my doubts: where is the best place to define helper functions: inside class or outside class? In both cases, how to make them accessable?
from tkinter import *
class TextEditor():
def __init__(self, root):
self.select_all() #helper function declare
myMenu = Menu(root, tearoff=0) #Menu bar
editMenu = Menu(root, tearoff)
editMenu.add_command(label="Select All", accelerator="Ctrl+A", command=select_all)
myMenu.add_cascade(label="Edit", menu=editMenu)
root.config(menu=myMenu)
textPad = Text(root, wrap="word", undo=True)
textPad.pack(expand="yes", fill="both")
def select_all(self):
textPad.tag_add('sel', '1.0', 'end')
if __name__ == '__main__':
root=Tk()
app = TextEditor(root)
root.mainloop()
This is the error:
Traceback (most recent call last):
File "C:\Python33\gui\tkguibook\textpad.py", line 21, in <module>
app = TextEditor(root)
File "C:\Python33\gui\tkguibook\textpad.py", line 6, in __init__
self.select_all() #helper function declare
File "C:\Python33\gui\tkguibook\textpad.py", line 17, in select_all
textPad.tag_add('sel', '1.0', 'end')
NameError: global name 'textPad' is not defined
Thank you in advance for your kind help!
First of all, I advise you to watch some tutorials on object-oriented paradigm in Python without using tkinter directly.
The problem with your code is that textPad is not a property of the class, but it's a simple local variable to the __init__ method or constructor. To make it a property, you should use self to declare and then refer to the just declared property.
For example, suppose I have the following class:
class TextEditor:
def __init__(self):
# stuff
and you want to add a property, visible in all the points in your class, you can do it in this way:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text() # using 'self' to declare a property
now, if you want to refer to that property in another method, you should use always the self:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text()
def set_text(self, new_text):
self.textPad.insert(tkinter.END, "hello") # using 'self' to refer to the property
To know more about self.

Run method with reference to it's static vars from a child class

I have a class Child which extends Test. I want to call a function from Test from Child.
I tried this:
class Test
constructor: ->
#i = 'hello world'
f1: -> console.log #i
f2: -> console.log 'hello'
class Child extends Test
run: ->
Test::f1()
hello = new Child()
hello.run()
When I call hello.run(), it calls Test.f1(), but the result is undefined. It's not setting the static variable #i before it's running Test.f1().
If I switch Test::f1() to Test::f2(), it gives me the correct result.
I need to know how should I make Test's constructor run when I create a new Child() so that #i is defined in Test when I run Test::f1() from Child.run().
Thanks! :D
Here's one way of doing it:
class Test
#i: 'hello world'
#f1: -> console.log #i
f2: -> console.log 'hello'
class Child extends Test
run: ->
Test.f1()
hello = new Child()
hello.run()
Notice, the i variable is static, so it doesn't make sense to set it in the constructor. Also, the f1 method is now static as well.
(I'm not an expert with CoffeeScript, so I'm not sure what the :: syntax is needed for.)
The constructor is being run when you create a new instance of Child. The problem is the way that you're invoking f1.
You don't want to say Test::f1(). You can just say #f1(), since Child is a subclass of Test. These are different in a very important way: Test::f1() does not set this, so when that function requests this.i, it finds only undefined, because this is set to Window (or something ridiculous like that in the browser, not sure if you're running this in Node). Saying #f1() is the same as saying Test::f1.call(this). This is one of the nice things that CoffeeScript's class system lets you do.
Finally, a pedantic note: there are no static variables in the code you've written. i, as you've written it, is an instance variable. Static variables look like this:
class Test
#staticVar = 1234
Or like this:
class Test
# ...
Test.staticVar = 1234
Instance variables look like this:
class Test
fn: ->
#instanceVar = 1234
Or like this:
test = new Test()
test.instanceVar = 1234
Or even like this (for the default value of an instance variable shared among all instances):
Test::instanceVar = 1234
In a similar vein:
When I call hello.run(), it calls Test.f1(), but the result is undefined. It's not setting the static variable #i before it's running Test.f1().
You're never calling Test.f1(); you're calling Test::f1(), which is very different. In the code you've written, there is no Test.f1, only Test.prototype.f1.

How can i reach a class variable from another class in Lua?

I am using director class for scene transitions and i need to use the variable in a class in another class. So how can i call it?
local a= require "welcome"
variableName is text display object in welcome class
print(a.variableName.text)
However i get nil.
Could you help me out? Thanks
Make the variable a property of the returned table:
local Class = {}
function Class.new()
local class = {}
class.variableName = display.newText("Hello mom!", 100, 100, "Helvetica", 18)
return class
end
return Class
Then you can reference it:
local a = require ("class").new()
print(a.variableName.text)
OR
If you want to pass variables between the screens in Rauber's Director Class, you can:
local parameters = {p1="some text", p2="some more text"}
director:changeScene(parameters, "sceneName")
In your screen, make the new function accept the parameters:
function new(parameters)
print(parameters.p1, parameters.p2) --> some text some more text
end
OR
Put _G in front of your variable
_G.myGlobalVar = "some awesome stuff"
Then you can reference it in another class
print(_G.myGlobalVar) --> some awesome stuff

Django-Nonrel with Mongodb listfield

I am trying to implement manytomany field relation in django-nonrel on mongodb. It was suggessted at to:
Django-nonrel form field for ListField
Following the accepted answer
models.py
class MyClass(models.Model):
field = ListField(models.ForeignKey(AnotherClass))
i am not sure where the following goes, it has been tested in fields.py, widgets,py, models.py
class ModelListField(ListField):
def formfield(self, **kwargs):
return FormListField(**kwargs)
class ListFieldWidget(SelectMultiple):
pass
class FormListField(MultipleChoiceField):
"""
This is a custom form field that can display a ModelListField as a Multiple Select GUI element.
"""
widget = ListFieldWidget
def clean(self, value):
#TODO: clean your data in whatever way is correct in your case and return cleaned data instead of just the value
return value
admin.py
class MyClassAdmin(admin.ModelAdmin):
form = MyClassForm
def __init__(self, model, admin_site):
super(MyClassAdmin,self).__init__(model, admin_site)
admin.site.register(MyClass, MyClassAdmin)
The following Errors keep popping up:
If the middle custom class code is used in models.py
name 'SelectMultiple' is not defined
If custom class code is taken off models.py:
No form field implemented for <class 'djangotoolbox.fields.ListField'>
You just need to import SelectMultiple by the sound of it. You can put the code in any of those three files, fields.py would make sense.
Since it's pretty usual to have:
from django import forms
at the top of your file already, you probably just want to edit the code below to:
# you'll have to work out how to import the Mongo ListField for yourself :)
class ModelListField(ListField):
def formfield(self, **kwargs):
return FormListField(**kwargs)
class ListFieldWidget(forms.SelectMultiple):
pass
class FormListField(forms.MultipleChoiceField):
"""
This is a custom form field that can display a ModelListField as a Multiple Select GUI element.
"""
widget = ListFieldWidget
def clean(self, value):
#TODO: clean your data in whatever way is correct in your case and return cleaned data instead of just the value
return value
You probably also want to try and learn a bit more about how python works, how to import modules etc.