Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I want to write a function that sets a self variable to None, but it feels very wrong to write a million functions for each variable.
I want to do something like:
class MyClass():
def __init__(self):
self.duck = None
self.dog = None
def makeduck(self):
self.duck = "Duck"
def makedog(self):
self.dog = "Dog"
def deleteVar(self,var):
self.var = None # or del self.var
I want to do this because the variables tend to be very large and I don't want to overload my ram so I have to delete some not needed vars depending on the context.
It is indeed possible.
Although having a clear separation between what should be program structure: variables, and data: text inside strings, Python allows one to retrieve and operate on variables or attributes given their name.
In this case, you will want to use the setattr and delattrcalls: both take an instance, an attribute name, given as textual data (a string), and operate on them like the corresponding assignment (self.var = xxx) and deleting (del self.var ). statements (but, as you intend to use, with "var" being a variable containign the actual attribute name).
def deleteVar(self, var):
# setattr(self, var, None). #<- sets attribute to None
delattr(self, var). # <- deletes attribute.
(for completeness: there is also the getattr call which allows attribute retrieval on the same bases)
That said: the memory usage of hard-coded variables, even if you have tens of them, will likely be negligible in a Python process.
Having tens of different "deleter" methods, however, would indeed be clumsy, and there are situations were your code might be more elegant by passing your attributes as data, as you intent.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I would like to convert all instance fields of an object into properties (getter only) in order to make them read only. The fields might be defined by a subclass.
How can I achieve this?
class SomeClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
convert_all_instance_fields_into_properties(self) # implementation ?
It is possible to achieve readonly fields using python builtins quite easily:
class X:
def __init__(self, val):
self.foo = val
def __setattr__(self, key, value):
if not hasattr(self, key): # only for first set
super(X, self).__setattr__(key, value)
else:
raise ValueError
def main():
x = X('bar')
y = X('baz')
assert x.foo == 'bar'
assert y.foo == 'baz'
# raises ValueError
x.foo = 'Raise an error!'
If you want to specify which fields are readonly
class X:
readonly = ['foo']
def __init__(self, val):
self.foo = val
def __setattr__(self, key, value):
if key in self.readonly and not hasattr(self, key):
super(X, self).__setattr__(key, value)
else:
raise ValueError
There are not such things as "private" in Python. If you want to and try hard enough, you can extract anything.
There are 2 levels of semi-private:
one underscore prefix for internal use, normally accessible outside - but most IDEs will underline it and warn about a not recommended practice
two underscore prefix for pseudo-private, still accessible if someone really wants it but ugly
Most of the time, you only want one underscore - people will access it only when they think they really need it.
In the code I'm working with, I saw two underscores used only as a way of encapsulating lazily loaded properties (one underscore was a "getter" and checked whether variable is already loaded).
Remember, that even with a "getter" you will be returning an object unless you return a copy yourself. Rethink your design, think in Python, rather than in "private" and "getters". ;)
Edit:
Seems like I misunderstood the question.
Functions marked with #property decorator will return without parentheses to call them (spam.eggs, instead of spam.eggs()) and be "read-only" (you can do bacon = spam.eggs but not spam.eggs = bacon).
BUT the rest of my comment still stands:
everything is accessible if one is determined enough
use underscores to ask people nicely not to access the value
if your getter property returns a mutable object, it will still be changeable inside (only reference will stay the same), e.g. eggs.list = [] will not work, but eggs.list.append("spam") will!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
can a self variable be defined inside the for loop? it is not defined anywhere before.
I am confused over its usage. the link from where the code is attached below.
def initialize_nb_dict(self):
self.nb_dict = {}
for label in self.labels:
self.nb_dict[label] = defaultdict(list)
https://github.com/taspinar/siml/blob/master/notebooks/Naive_Bayes.ipynb
Yes, it can. self is the class instance; you can create and set attributes. In the same way that you can do:
>>> class A: pass
...
>>> a = A()
>>> a.nb_dict = {}
>>> a.nb_dict[1] = 2
>>> a.nb_dict
{1: 2}
Within the scope of the method initialize_nb_dict(), self is the instance (like a above.)
There's nothing special about self, except that it is used by convention to refer to the instance for instance methods. (You could even call a as self, but it would be unconventional to name an instance self outside of an instance method.)
One other minor point on terminology: you say "can a self variable be defined." It's probably more accurate to say that an attribute of self is being set, rather than that self is being defined; it's "defined" when the instance is implicitly passed as self to the method.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
As a general strategy, is there a way to add objects to init, without initialization, while the code is being executed. For example, instead of:
class Test:
def __init__(self):
self.a = False
self.b = False
def set_values(self, in_boolean):
if in_boolean:
self.a = True
else:
self.b = True
Do this:
class Test:
def __init__(self):
self.a = False
def set_values(self, in_boolean):
if in_boolean:
self.a = True
else:
self.b = True
# This object is only created if this condition is
# met. Otherwise, this is not created in __init__.
Does one need to initialize any and all objects in __init__ if they want to save an object there?
If this is not possible, what is an alternative method for creating global objects that are created within a class method?
I'll explain a scenario when I would want to use this so as to better illustrate the question:
Say I am executing a method within a class. Depending on certain conditions, an object may or may not be generated within that class that I would like to be able to access from all other methods within the class. Because the object may or may not be created, I don't wish to initialize it in __init__.
To sum it up: If I want to 'save' an object on my class, do I need to initialize it in __init__?
EDIT
Ok so my problem was that I believed one only created "self." objects in init. As I understand it now, one can make a "self." object anywhere in the class, not just in init. This would make said object accessible from anywhere else in the class, which is ultimately what I am looking for here. Maybe the question should have been:
How to I make objects accessible from anywhere in it's class?
In Python, you don't need to 'declare' a variable before you use it at all. If you try to access a variable that doesn't exist, you can just wrap it in a try...except AttributeError and call it a day.
The __init__ on a class is just like any other method on Python, it doesn't have access to any sort of functionality that the others don't. The only difference is that it has the benefit of being automatically called whenever you instantiate your class, saving you the trouble of having to write a constructor-like class every time and call it manually.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have the following piece of Python:
class CollectorGUI(Gtk.Window):
def __init__(self, prefill, flags, data_to_return):
"""prefill should be an instance of the Prefill class"""
self.prefill = prefill
self.flags = flags
self.data_to_return = data_to_return
......
My question is: (1) how to get rid of the documentation string? I want my code to be self-documenting; (2) how to get rid of these three lines:
self.prefill = prefill
self.flags = flags
self.data_to_return = data_to_return
Is there an abbreviation?
The Prefill requirement can be documented in the method signature using function annotations:
class CollectorGUI(Gtk.Window):
def __init__(self, prefill: Prefill, flags, data_to_return):
Annotations are discoverable at runtime, just like the docstring is. Annotations are not enforced (they are meant as a more generic stepping stone for different use cases) but are immediately obvious in the signature.
You can then optionally enforce it explicitly by asserting the type:
assert isinstance(prefill, Prefill), 'prefill must be an instance of Prefill'
As for auto-setting your attributes from the function arguments, that's answered elsewhere: What is the best way to do automatic attribute assignment in Python, and is it a good idea?
While you could use inspect to automatically create attributes from the arguments in the method's signature, it would obfuscate the perfectly readable code you have now.
One look at the constructor tells me that the class at least has the attributes prefill, flags, and data_to_return.
Making explicit code implicit is often not a good idea.
But if you insist:
import inspect
class C(object):
def __init__(self, a, b, c):
spec = inspect.getargspec(getattr(C, "__init__"))
for arg in spec.args[1:]:
setattr(self, arg, locals()[arg])
c = C(1, 2, 3)
print c.a
print c.b
print c.c
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I know (?) about theory behind __new__ constructor in Python, but what I ask about is common practice -- for what purpose is this constructor really (!) used?
I've read about initializing immutable objects (the logic is moved from __init__ to __new__), anything else? Factory pattern?
Once again, please note the difference:
for what task __new__ can be used -- I am not interested
for what tasks __new__ is used -- I am :-)
I don't write anything in Python, my knowledge is from reading, not from experience.
Where you can actually answer the question: Common practice of new constructor?
The point of __new__ is to create an empty object instance that __init__ then initializes. Reimplementing __new__ you have full control of the instance you create, but you stop short of actually using the __init__ method to do any further processing. I can give you two cases where this is useful: automatic creation of methods and deserialization from disk of a class with a smart constructor. These are not the only ways you can solve these two problems. Metaclasses are another, more flexible way, but as any tool, you have different degrees of complexity you may want to get.
Automatic creation of methods
suppose you want to have a class that has a given set of properties. You can take control how these properties are initialized with code like this
class Foo(object):
properties = []
def __new__(cls, *args):
instance = object.__new__(cls, *args)
for p in cls.properties:
setattr(instance, p, 0)
return instance
class MyFoo(Foo):
properties = ['bar', 'baz']
def __init__(self):
pass
f=MyFoo()
print dir(f)
the properties you want are directly initialized to zero. You can do a lot of smart tricks, like doing the properties list dynamically. All objects instantiated will have those methods. A more complex case of this pattern is present in Django Models, where you declare the fields and get a lot of automatic stuff for free, thanks to __new__ big brother, metaclasses.
Deserialization from disk
Suppose you have a class with a given constructor that fills the fields of the class from an object, such as a process:
class ProcessWrapper(object):
def __init__(self, process):
self._process_pid = process.pid()
def processPid(self):
return self._process_pid
If you now serialize this information to disk and want to recover it, you can't initialize via the constructor. So you write a deserialization function like this, effectively bypassing the __init__ method you can't run.
def deserializeProcessWrapperFromFile(filename):
# Get process pid from file
process = ProcessWrapper.__new__()
process._process_pid = process_pid
return process