How to avoid object creation in python? - 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.

Related

Is it possible to restrict attributes to be defined only in __init__ in python? [duplicate]

This question already has answers here:
Prevent creating new attributes outside __init__
(13 answers)
Closed 7 years ago.
I'm writing code with a lot of class definition, and I want to make all the attributes of class only being defined in __init__().
The main reason is that avoiding my own fault to define new (unexpected) attributes and I don't want new attributes to be defined when the module is imported to run (see the following).
You can run this code with impunity, which I'm trying to avoid.
class A():pass
a=A()
a.a=1
print(a.a)
Here are two options:
First, you could use __slots__, which will restrict your class to a specific set of attributes.
Not exactly what you want (and slots weren't designed for this in the first place!), but close-ish:
class A(object):
__slots__ = ["a"]
a = A()
a.a = 1 # Will work
a.b = 2 # Will not work
Second, you could override __setattr__, and have it look up a flag to prevent creating new attributes after init has completed:
class A(object):
__frozen__ = False
def __init__(self, a):
self.a = a
self.__frozen__ = True # At this point no more changes can be made
def __setattr__(self, attr, value):
if self.__frozen__ and not hasattr(self, attr):
raise Exception("New attributes cannot be added!") # Create your own Exception subclass for this
super(A, self).__setattr__(attr, value)
a = A(1)
a.a = 2 # Works
a.b = 2 # Throws an Exception
This is closer to what you want. However, you should think hard about whether this is actually desirable. Is this the best way to avoid mistakes? Maybe you'd want to e.g. write tests instead?
Among other things, this will break subclassing if your subclass calls super(TheSubClass, self).__init__(*args, **kwargs) and then tries to access an attribute.
You want Slots:
class MyAttrOnly:
__slots__ = ('a', 'b')
m = MyAttrOnly()
m.d = "doesn't work"
This will throw an exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MyAttrOnly' object has no attribute 'd'

Python decorator with same name as an instance method

I have a very similar question to this except I would like to name my function property
so for example Id like to do something like:
class ThingWithProperties(object):
def property(self, a):
print("in property", a)
#property
def test(self):
print("in test")
t = Testing()
t.property(1)
t.test()
But I get the following error:
Traceback (most recent call last):
File "test.py", line 5, in <module>
class ThingWithProperties(object):
File "test.py", line 10, in ThingWithProperties
#property
TypeError: property() missing 1 required positional argument: 'a'
Could someone please explain why this is happening? As well as how to work around it (without renaming my instance method)?
This is happening because by defining a method called property, you are shadowing the builtin property within the scope of the class declaration. Hence when you write #property, your method is called to decorate test as opposed to the builtin property.
You could use the __builtin__ module to explicitly use the builtin property:
class ThingWithProperties(object):
def property(self, a):
print("in property", a)
#__builtin__.property
def test(self):
print("in test")
Though I personally always avoid shadowing builtins, even if they are only shadowed in a limited scope, as is the case here.
To be a little more clear about the "shadowing" going on, try running this in your interpreter:
foo = 42
print(foo)
class Test:
foo = 73
print(foo)
print(foo)
There are two points to make here: First, some might be surprised that we can print things in a class definition. The point is that a class definition is a code block like any other, and you can write for-loops and print all you'd like, and whatever variables or functions you create are gathered together into a class dictionary when it comes time to actually create the class.
The second point is that the class definition creates a new scope, and the value of foo inside the scope is different than outside. That is, the above prints 42, then 73, then 42 again.

How does one write a method to call after a variable or object, such as "string {0}".format(stringy)?

For different data types, like string, there are methods that you call by adding a dot after, such as:
"string {0}".format(stringy)
or
listx.remove(x)
How is the information being passed to the method? How can I write a function like that?
class YourObject(object):
def do_something(self):
print('doing something')
Then you can use your object:
your_object = YourObject()
your_object.do_something()
This shows how to create an object, and call a method on it (like theexamples you provided in your post).
There are way more in-depth tutorials/blogs about object creation and custom classes. A good place to start is always the standard documentation.
You can create a custom class and then include whatever methods you want. Below is an example:
>>> class MyClass(object): # Define class MyClass
... def __init__(self): # Define MyClass' constructor method
... self.name = "Me" # Make an attribute
... def getName(self): # Define method getName
... return self.name # Return MyClass' attribute name (self.name)
...
>>> test = MyClass() # Initialize (create an instance of) MyClass
>>> print test.getName() # Print the name attribute by calling the getName method
Me
>>>
Basically, you are working with OOP (Object-Oriented Programming). However, since this concept is so large, I can't demonstrate/explain everything you can do with it here (otherwise my post would be enormous). My advice is to research OOP and Python classes. There are many good tutorials you can find. I gave one above; here is another:

Python 2: export class attributes from a local variable to the class itself

I'm not really sure how best to explain what I want, so I'll just show some code:
class Stuffclass():
def add(self, x, y):
return x + y
def subtract(self, x, y):
return x - y
# imagine that there are 20-30 other methods in here (lol)
class MyClass:
def __init__(self):
self.st = Stuffclass()
def doSomething(self):
return self.st.add(1, 2)
m = MyClass()
m.doSomething() # will print 3
# Now, what I want to be able to do is:
print m.add(2, 3) # directly access the "add" method of MyClass.st
print m.subtract(10, 5) # directly access the "subtract" method of MyClass.st
m.SomeMethod() # execute function MyClass.st.SomeMethod
I know I could do something like this:
class MyClass:
def __init__(self):
self.st = Stuffclass()
self.add = self.st.add
self.subtract = self.st.subtract
...but this requires manually assigning all possible attributes.
I'm writing all the classes so I can guarantee no name collisions.
Making MyClass a subclass of Stuffclass won't work, because I actually am using this in a plugin-based application, where MyClass loads other code dynamically using import. This means MyClass can't subclass from the plugin, because the plugin could be anything that follows my API.
Advice please?
I believe that writing a getattr function for your class will let you do what you want.
Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception
So something as simple as:
def __getattr__(self, name):
if hasattr(self.st, name):
return getattr(self.st, name)
else:
raise AttributeError
should do roughly what you're after.
But, having answered (I think) the question you asked, I'm going to move on to the question I think you should have asked.
I actually am using this in a plugin-based application, where MyClass loads other code dynamically using import. This means MyClass can't subclass from the plugin, because the plugin could be anything that follows my API
I can see why MyClass can't be a subclass of StuffClass; but couldn't StuffClass be a subclass of MyClass? If you defined the inheritance that way, you'd have a guarantee what StuffClass implements all the basic stuff in MyClass, and also that your instances of StuffClass have all the extra methods defined in StuffClass.
From your mention that the plugins need to "follows my API", I'm assuming that might be a case where you need to ensure that the plugins implement a set of methods in order to conform with the API; but since the implementation of the methods is going to depend on the specifics of the plugin, you can't provide those functions in MyClass. In that case, it sounds as though defining an Abstract Base Class that your plugins are required to inherit from might be useful for you.
Use __getattr__ to delegate the calls to Stuffclass's instance:
class MyClass:
def __init__(self):
self.st = Stuffclass()
def __getattr__(self,attr):
return getattr(self.st,attr)
Demo:
>>> from so import *
>>> m = MyClass()
>>> m.add(1,2)
3
>>> m.subtract(100,2)
98

Constant instance variables?

I use #property to ensure that changes to an objects instance variables are wrapped by methods where I need to.
What about when an instance has an variable that logically should not be changed? Eg, if I'm making a class for a Process, each Process instance should have a PID attribute that will frequently be accessed but should not be changed.
What's the most Pythonic way to handle someone attempting to modify that instance variable?
Simply trust the user not to try and change
something they shouldn't?
Use property but raise an
exception if the instance variable is
changed?
Something else?
Prepend name of the variable with __, and create read-only property, Python will take care of exceptions, and variable itself will be protected from accidental overwrite.
class foo(object):
def __init__(self, bar):
self.__bar = bar
#property
def bar(self):
return self.__bar
f = foo('bar')
f.bar # => bar
f.bar = 'baz' # AttributeError; would have to use f._foo__bar
Simply trusting the user is not necessarily a bad thing; if you are just writing a quick Python program to be used once and thrown away, you might very well just trust that the user not alter the pid field.
IMHO the most Pythonic way to enforce the read-only field is to use a property that raises an exception on an attempt to set the field.
So, IMHO you have good instincts about this stuff.
Maybe you can override __setattr__? In the line of,
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
raise TypeError, 'value is read only'
self.__dict__[name] = value
Simply use a property and a hidden attribute (prefixed with one underscore).
Simple properties are read-only!
>>> class Test (object):
... #property
... def bar(self):
... return self._bar
...
>>> t = Test()
>>> t._bar = 2
>>> t.bar
2
>>> t.bar = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
Hiding with double underscore is not used to hide the implementation, but to make sure you don't collide with a subclass' attributes; consider a mixin for example, it has to be very careful!
If you just want to hide the attribute, use a single underscore. And as you see there is no extra magic to add -- if you don't define a set function, your property is just as read-only as the return value of a method.

Categories

Resources