Defining global accessors - python

I have two Python files:
"testclass.py":
class TestClass:
Result = 0
def __init__(self):
self.Result = 1
return
Manager = TestClass()
and "hostapp.py":
import testclass
print Manager.Result # should equal 1
I'd prefer to simply include the accessory class (testclass) in my main class, then use an accessor that's already been initialized, but when I run hostapp.py, I get the following error:
NameError: name 'Manager' is not defined
Would someone please explain to me why the "global" variable Manager (which should be an instance of TestClass) is only accessible from within the class? I know I can access it using:
testclass.Manager
but that's not how I planned to access it. Help?
Edit:
After making the change suggested by Martineau, the accessor works as intended:
from testclass import Manager

Related

Basics about Python class

I'm trying to learn about the basic construction of the python class. I have the following code which is completely running fine:
class Test1:
name = 'Choton'
age = 28
class Test2: # __init__ function executes whenever the class is called
def __init__(self):
self.name = 'Choton'
self.age = 28
print('Class Test2 is called and initialized...')
def main():
# Test1
print(f'Test1:')
print(f'Test1().name = {Test1().name}, Test1().age = {Test1().age}')
print(f'Test1.name = {Test1.name}, Test1.age = {Test1.age}\n')
# Test2
print(f'Test2:')
print(f'Test2().name = {Test2().name}, Test2().age = {Test2().age}')
# DOES NOT WORK
# print(f' name = {Test2.name}, age = {Test2.age}')
if __name__ == '__main__':
main()
I know that the __init__ function always runs whenever a class is initialized. Here the Test1 class do not have any __init__ function and both Test1.name and Test1().name works fine. But whenever I am calling the name using the __init__ function in Test2, the Test2.name does not work anymore. It says the following error if I uncomment that line: AttributeError: type object 'Test2' has no attribute 'name'.
What is the difference in here? Why both syntax work for one class and not for the other? I am a bit confused about it. Is there any syntactic sugar in here or any generalization that I am missing?
In Test1 you are defining class variables, which are shared between all objects, and can be accessed by using the class only (Test1.name) as well as from the instance (Test1().name).
Defining self.name in Test2.__init__ makes it an instance variable, which is only available on a specific instance of the class, e.g. new object created by Test2()
Took me a long time to get my head around classes, I'm still not there. The init function isn't needed in every class, one thing it's used for is to allocate different values to the class attributes.
For info,
Test1 is the class.
Test1() is an instance of the class.
Both can be assigned. So you could say:
MyClassInstanceA = Test1()
MyClassInstanceB = Test1()
... These two are different items because they are both instances of the Test1 class, each instance is unique.
Or you could say
MyClassA = Test1
MyClassB = Test1
... These two are the same thing as they are both allocated Test1, not Test1()....
name and age are attributes. In the case of Test1 they are "class attributes". That is, the exist at the class level. They can be accessed via the class or an instance of the class. Remember Test1 is the class Test1() is an instance of the class.
The subtle difference between Test1() and Test1 is what is causing the error.
To further explain. In the Test1 class, the two attributes name and age exist in the class, before we create an instance of the class. If we do create any instances name and age attributes will be the same across all instances. But the important thing here is we don't have to create an instance of the class to access them. That's why Test1.name works....
On the other hand, in Test2 class. The attributes are only created when the class is initiated (this is what the init function is doing). They don't exist until then. So, when we want to access them you need to access them via an instance of the class Test2().name....
MyClassC = Test2
... Still no instance of the class so name or age doesn't exist
MyClassInstanceD = Test2()
... Now we have an instance of the class so name and age exists and it is accessed via that class which is called MyClassInstanceD...
MyClassInstanceD.name = 'Choton'
But as name and age only exist in the instance we can still not call
Test2.name
as this still doesn't exist and never will unless you modify the Test2 class...

How to Invoke parametrized Constructor if class name Dynamically Identified in Python

I am new in Python before I have only Java experience , In python I need to invoked parameter constructor while I have many class and class name identifies on runtime so I need to create that class Object with constructor and as well method. with static it is working fine. for java I can use class.forName(class_name). I tried with importlib, string to class but did not work.
Excample:
class A
def _init_(self,name):
self.name = name
def some_method(self):
print('method print',self.name)
Expectation: want to achieve-
instance = A('instance A')
instance.some_method()
in the above code class A will be identified on Run time and similar many class we have and above code I need to implement dynamically, how can achieve this.
If classes are in another file, use getattr
import module_with_my_classes
x = getattr(module_with_my_classes, 'A')
If you are in the file as the class definitions, use globals
x = globals()['A']
# x is a A instance

Dynamically create a class inherited from neomodel.StructuredNode

Python's library neomodel provides the ability to define a relationship with a class that hasn't been defined yet, by using its name as string, which works fine as follows:
from neomodel import StructuredNode, RelationshipTo
# if Foo is already defined
class Bar (structuredNode):
rel = RelationshipTo(Foo, 'REL')
# if Foo isn't defined
class Bar(StructuredNode):
rel = RelationshipTo('Foo', 'REL')
I want to create a class in the runtime and provide it with the attribute RelationshipTo, which should make a relationship with undefined yet class, so I did:
Bar = type('Bar', (StructuredNode,), {'rel': RelationshipTo('Foo', 'REL')})
In some point in the runtime later, I define Foo:
Foo = type('Foo', (StructuredNode,), {})
Now if I want to use the class I've just made:
bar = Bar()
The next error still pops up as if I haven't defined Foo:
AttributeError: module '_pydevd_bundle.pydevd_exec2' has no attribute
'Foo'
Note: This error doesn't appear if I at least define Bar statically (not in the runtime)
Would someone explain why that happens and how to define them properly in runtime, please?
I appreciate any help!

Execute Method within Class Python

I'm trying to call a method within a class MyClass and have its value returned.
class MyClass:
def __init__(self):
print " Class Initialized"
def gather_path(self):
self.tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
return self.tld_object
How do I return the value of self.tld_object by importing my class in Python intrepreter.
I'm importing like:
from MyApp.MyClass import gather_path()
I know, this is quite basic - I'm relatively new to OOP in Python.
how do I then call this method to return the value of return self.tld_object within gather_path() method?
It depends on what you're trying to do, but typically, I think the code importing your class would look like this:
from MyApp import MyClass
my_instance = MyClass()
value = my_instance.gather_path()
The value variable will now contain tld_object's value.
If you don't want to instantiate MyClass in order to call get_path(), you need to make get_path() either a class or static method.
From your example, it's not clear that you need to set self.tld_object, since you're just returning it from gather_path() anyway, unless other methods are relying on that state under the hood. If you are, though, it would be better practice to declare it in __init__, even if you set it to None. Alternatively, if all instances of MyClass are going to use the same value of tld_object, you could make it a class variable, and just declare it outside of any method, like so:
class MyClass:
tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
def gather_path(self):
return self.tld_object
Not sure how much of that is relevant to your needs, it's a bit hard to tell from the given example. If I were writing this (given what you've said so far), I'd do the following:
class MyClass:
def __init__(self):
self.tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
# Maybe raise an exception or something if self.tld_object doesn't get set right
# Example of how to access tld_object from another method
def print_tld_object(self):
print self.tld_object
If you need to reach tld_object from outside the class, you would do the following in the other module:
from MyApp import MyClass
my_instance = MyClass()
tld = my_instance.tld_object

How to avoid object creation in python?

I am new to python programming,I have one class,for this class i created one object( obj1).i don't want to create other than this object,if any body wants to create one more object for this class that should refer to first object only(instead of creating one more object).how to do this? please refer the below code?
class MyClass:
def __init__(self):
pass
obj1=MyClass()//create object
obj2=MyClass()//avoid creation and refer obj2 to obj1
obj3=MyClass()//avoid creation and refer obj3 to obj1
So you want something singleton-ish? Then do not use objects for this at all. Simply put the functions in a separate module (.py file) and put your variables in the module scope (e.g. global variables) - that's the pythonic way to do what you want if you do not need thread safety. Remember: It's not java and using classes for everything is not the way to go.
However, here's some code that allows only one instance:
class MyClass:
def __init__(self):
if getattr(self.__class__, '_has_instance', False):
raise RuntimeError('Cannot create another instance')
self.__class__._has_instance = True
If you want singletons, have a look at Python and the Singleton Pattern and Is there a simple, elegant way to define singletons?
Here's a simple way -- hide the class name:
class obj:
pass
obj = obj()
Which will make class obj instances more difficult to create afterwards -- but not impossible, as pointed out in the comments.
Another alternative, delete the class after its first use:
class MyClass:
def method(self): print 'spam'
obj1 = MyClass()
del MyClass
obj1.method() # show instance still exists
obj2 = MyClass()
Output:
spam
Traceback (most recent call last):
File "noclass.py", line 7, in <module>
obj2 = MyClass()
NameError: name 'MyClass' is not defined
You could create the single object and make it a global i.e top-level object in the module using it if all you are coding would go in a single file or you could put it in a seperate module and import it.

Categories

Resources