Can anyone help me with the correct syntax to call my method __get_except_lines(...) from the parent class?
I have a class with a method as shown below. This particular method has the 2 underscores because I don't want the "user" to use it.
NewPdb(object)
myvar = ...
...
def __init__(self):
...
def __get_except_lines(self,...):
...
In a separate file I have another class that inherits from this class.
from new_pdb import NewPdb
PdbLig(NewPdb):
def __init__(self):
....
self.cont = NewPdb.myvar
self.cont2 = NewPdb.__get_except_lines(...)
And I get an attribute error that really confuses me:
AttributeError: type object 'NewPdb' has no attribute '_PdbLig__get_except_lines'
Your problem is due to Python name mangling for private variable (http://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references). You should write:
NewPdb._NewPdb__get_except_lines(...)
super(<your_class_name>, self).<method_name>(args)
e.g.
super(PdbLig, self).__get_except_lines(...)
The entire point of putting a double underscore in front of a name is to prevent it from being called in a child class. See http://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references
If you want to do this, then don't name it with a double underscore (you can use a single underscore), or create an alias for the name on the base class (thus again defeating the purpose).
Related
I would like to instantiate a single class if a string var matches the name of the class. In similar questions, there seems to be a dependency that the name of the class is known at the start. In my case, I only know that the input string will match the name of a class. I want to use the string to identify which class (out of many choices) I need to instantiate. I.E. load the class with the same name as the string;
If string-var == a class (in a module file) in a directory, instantiate that class.
I thought the new getattr would help, but that seems to be for methods/functions as opposed to a class itself. I also considered issubclass, but the parameter needs to be a class, not a string. Any suggestions are greatly appreciated!
You should explicitly define an interface that maps a publicly known string to a reference to the class:
class Foo:
...
class Bar:
...
classes = {"foo": Foo, "bar": Bar}
Then you can lookup the appropriate class in the dict using your string (which, as you'll note, is not required to be the name of the class):
cls_name = "foo"
obj = classes[cls_name]()
I have the following classes:
class A:
def name(self):
return self.__label
class B(A):
def __init__(self, name)
self.__label = name
ex1 = B('Tom')
print ex1.name()
What I get is:
AttributeError: B instance has no attribute '_A__label'
What's wrong and how to correct it?
When you prefix an attribute with a double underscore, Python uses 'name mangling' to access the attribute. This means it will store the attribute on the class in the format: _<class name>__<attr name>. In your example self.__label will be stored as self._B__label because you set it in the B class method. But when you try to use the attribute in the A class it converts self.__label into self._A__label and finds that it isn't set.
The use case for double underscores is when you want to ensure that your variable is always on your class even if a subclass derives your class. Because what could happen is that the subclass redefines your variable to something else, using double underscored variables makes this that much harder.
I'm trying to modify class attribute by reference to object in __init__ method and then use it in another method. Sadly the following code sample doesn't work as expected...
CODE
class Translator:
#list of attributes
parser=None
def __init__(self):
parser = Parser_class() ...
#some other commands
def Translate(self):
something=self.parser.GenerateHead() ...
#more commands
COMPILE ERR
AttributeError: 'NoneType' object has no attribute 'GenerateHead'
I know that I can give it to the Translate method as argument, I'm just curious why this statement within Python doesn't work.
You're doing your instance attributes wrong.
First off, you don't need to declare your attributes ahead of time. Putting parser = None at the top level of the class creates a class variable named parser, which I don't think is what you want. Usually in Python you can add new instance attributes at any time by a simple assignment: instance.attr = "whatever".
Second, when you want to do an instance assignment from within a method, you need to use self to refer to the instance. If you leave off self, you'll be assigning to a local variable inside your function, not to an instance or class variable. Actually, the specific name self isn't necessary, but you do need to use the first argument to the method (and it's probably not a good idea to break the convention of naming that self).
So, to fix your code, do this:
class Translator:
# don't declare variables at class level (unless you actually want class variables)
def __init__(self):
self.parser = Parser_class() # use self to assign an instance attribute
def Translate(self):
something = self.parser.GenerateHead() # this should now work
I want to call a redefined private method from an abstract parent class. I am using django if that matters.
class Parent(models.Model):
def method1(self):
#do somthing
self.__method2()
def method2(self):
pass # I also tried calling up a prent method with super
class child(Parent):
def method1(self)
super(Child, self).method1()
def __method2(self):
#do something
I get a
AttributeError: "'Chil' object has no attribute '_Parent__method2'"
What I am doing wrong ?
Initial double underscores prevent polymorphism since both the method definition and the method call get mangled, to two different names. Replace with a single underscore to fix this.
Also, double underscores are not used for "private" attributes, and you should discard whatever reference told you that they are. They're used for MI disambiguation.
I wanted to do something like setattr to a class in class method in Python, but the class doesn't exist so I basically get:
NameError: global name 'ClassName' is not defined
Is there a way for a class method to modify the class? Something like this but that actually works:
class ClassName(object):
def HocusPocus(name):
setattr(ClassName, name, name)
HocusPocus("blah")
HocusPocus("bleh")
Class methods get the class passed as the first argument:
class Bla(object):
#classmethod
def cm(cls,value):
cls.storedValue = value
Bla.cm("Hello")
print Bla.storedValue # prints "Hello"
Edit: I think I understand your problem now. If I get it correctly, all you want to do is this:
class Bla(object):
storedValue = "Hello again"
print Bla.storedValue # prints "Hello again"
Class creation in Python (pretty much) simply means:
Create a fresh namespace.
Run the code that you find inside the class body using this namespace
Put everything that's left in the namespace into the class as class attributes.
Since storedValue is in the namespace after step 2, it's turned into a class attribute in step 3.
Another way you could do this would be to use a class decorator, though these are only available from Python 2.6 onwards IIRC.
Something like this:
def addattributes(cls):
cls.foobar = 10
return cls
#addattributes
class MyClass(object):
pass
print MyClass.foobar
This kind of this most useful when you want to "decorate" a number of classes with some specific functionality / properties. In your case, if you only want to do this once, you might just want to use class methods as previously shown.
While many good suggestions have been advanced, the closest one can get to the originally requested code, that is:
class ClassName(object):
def HocusPocus(name):
setattr(ClassName, name, property(fget=..., fset=...))
HocusPocus("blah")
HocusPocus("bleh")
is this:
class ClassName(object):
def HocusPocus(name):
return property(fget=..., fset=...)
blah = HocusPocus("blah")
bleh = HocusPocus("bleh")
I'm assuming the mysterious ... redacted parts need access to name too (otherwise it's not necessary to pass it as an argument).
The point is that, within the class body, HocusPocus is still just a function (since the class object doesn't exist yet until the class body finishes executing, the body is essentially like a function body that's running in its local dict [without the namespace optimizations typically performed by the Python compiler on locals of a real function, but that only makes the semantics simpler!]) and in particular it can be called within that body, can return a value, that value can be assigned (to a local variable of the class body, which will become a class attribute at the end of the body's execution), etc.
If you don't want ClassName.HocusPocus hanging around later, when you're done executing it within the class body just add a del statement (e.g. as the last statement in the class body):
del HocusPocus