Is this a bug in Python inheritance? [duplicate] - python

This question already has answers here:
Why do attribute references act like this with Python inheritance? [duplicate]
(3 answers)
How to avoid having class data shared among instances?
(7 answers)
Closed 10 years ago.
I'm not sure if the output of this code is correct or a bug:
class F:
"""An abstract class"""
list_of_secrets = []
def __init__(self):
pass
def getSecret(self):
return self.list_of_secrets
class F_None(F):
pass
class F_Some(F):
def __init__(self):
self.list_of_secrets.append("secret value!")
x = F_Some()
print "x:",x.getSecret()
y = F_None()
print "y:",y.getSecret()
The output using python 2.7.3:
x: ['secret value!']
y: ['secret value!']
I think it should output:
x: ['secret value!']
y: []
Any thoughts?

list_of_secrets is scoped to the class here. You want to instead attach it to self in __init__
def __init__(self):
self.list_of_secrets = []

You never define self.list_of_secrets. You only define F.list_of_secrets, which is entirely different. Do this instead:
class F:
"""An abstract class"""
def __init__(self):
self.list_of_secrets = []
def getSecret(self):
return self.list_of_secrets

Related

Creating classes dynamically in python [duplicate]

This question already has answers here:
How can I dynamically create derived classes from a base class
(4 answers)
Closed 10 months ago.
Is it a good coding practice to have the class name as variable.
E.g
def create_class(class_name):
class class_name:
def __init__(self):
do_sth....
class_instance = class_name()
return class_instance
for object in objects:
res = create_class(object)
I wanted to create different classes which are present in a list like objects=[person,vehicle, location ..]. What could be other alternative way to do it ?
class_name is a class, you can set a name property for your class, like this:
class class_name:
def __init__(self,name):
self.name = name
def __str__(self):
return str(self.name)
objects=["person","vehicle","location"]
for obj in objects:
res = class_name(obj)
print(res)

Call Python non-member function referenced by class variable [duplicate]

This question already has an answer here:
Assign external function to class variable in Python
(1 answer)
Closed 3 years ago.
In my class I'd like to call a non-member function whose reference is stored in a member variable. My issue is that it tries to pass self to the function as the first argument. How can I avoid this?
class MyClass:
my_useful_static_function = crcmod.mkCrcFun(0x11021, True)
def __init__(self):
# this gets called with the first argument as self :(
result = self.my_useful_static_function()
Use staticmethod:
class MyClass:
my_useful_static_function = staticmethod(crcmod.mkCrcFun(0x11021, True))
def __init__(self):
result = self.my_useful_static_function()
You need to use staticmethod like so:
class Foo:
#staticmethod
def my_method():
print("This is a static method")
def my_other_method(self):
print("This is not static")
# This works
Foo.my_method()
# This won't work
Foo.my_other_method()
# This works though
foo_instance = Foo()
foo_instance.my_other_method()

giving error while accessing method outside of class [duplicate]

This question already has answers here:
Python NameError: name is not defined
(4 answers)
Closed 4 years ago.
class one(object):
b=squares
def squares(self):
print('hi')
getting the following error:
NameError: name 'squares' is not defined
This should work for you. Let me explain it. First code should go inside of methods, these methods can be combined into classes. You shouldn't place code in the class directly.
In Python when an object is instantiated the __init__(self) method is called directly. This method takes the self argument which will hold the attributes and functions available for this class. In our case, I added an attribute called self.size = 5. Then we call the squares(self) function. Notice we access it as self.function_name().
Then in that function we pass the self argument. Notice how we can access the self.size attribute from this function.
class one(object):
def __init__(self):
self.size = 5
b = self.squares()
def squares(self):
print('hi' + str(self.size))
o = one()
If you want a generic function not tied to your object. Then you need to define it before the class.
def squares(a):
return a*a
class One():
def __init__(self, a):
self.num = a
self.example()
def example(self):
b=squares(self.num)
print(b)
obj = One(4)

is there a way to bind parameter to a function variable in python? [duplicate]

This question already has answers here:
Python Argument Binders
(7 answers)
Closed 6 years ago.
Consider the following example:
class foo:
def __init__(self):
print ("Constructor")
def testMethod(self,val):
print ("Hello " + val)
def test(self):
ptr = self.testMethod("Joe") <---- Anyway instead of calling self.testMethod with parameter "Joe" I could simple bind the parameter Joe to a variable ?
ptr()
k = foo()
k.test()
In the defintion test is it possible for me to create a variable which when called calls the method self.testMethod with the parameter "Joe" ?
Either use a functools.partial() object or a lambda expression:
from functools import partial
ptr = partial(self.testMethod, 'Joe')
or
ptr = lambda: self.testMethod('Joe')
You could pass a name to the constructor (and store it on the class instance), this is then accessible to methods:
class Foo:
def __init__(self, name):
print("Constructor")
self.name = name
def testMethod(self):
print("Hello " + self.name)
def test(self):
self.testMethod()
As follows:
k = Foo("Joe")
k.test() # prints: Hello Joe

Calling an inherited property in python [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Polymorphism in Python
Hi
I'm trying to call a property in a class, that is inherited from my baseclass, but it doesn't work. I guess I'm missing something, but what?
Here is my code:
class Produkt:
def __init__(self,pID,pProdNavn,pNetto):
self.__produktId = pID #atributt for produkt nummer
self.__produktNavn = pProdNavn #atributt for produkt navn
self.__produktNetto = pNetto #egenskap for nettopris
def getName(self): #Metode for å finne produktnavnet
return self.__produktNavn
class Bok(Produkt):
def __init__(self,pID,pProdNavn,pNetto,pForfatter):
Produkt.__init__(self,pID,pProdNavn,pNetto)
self.__produktForfatter = pForfatter #atributtp for forfatter
def getNet(self):
return self.__produktNetto
as you see I'm trying to call the _productNetto property that is inherited from my Produkt class.
What am I doing wrong?
/Andy
It works fine if you don't use double underscore in attribute names
class Produkt:
def __init__(self,pID,pProdNavn,pNetto):
self.produktId = pID
self.produktNavn = pProdNavn
self.produktNetto = pNetto
def getName(self):
return self.__produktNavn
class Bok(Produkt):
def __init__(self,pID,pProdNavn,pNetto,pForfatter):
Produkt.__init__(self,pID,pProdNavn,pNetto)
self.produktForfatter = pForfatter
def getNet(self):
return self.produktNetto
x = Bok(1, 2, 3, 4)
print x.getNet()
output:
3
Otherwise the names get mangled and it is looking for attribute _Bok__produktNetto. See: http://docs.python.org/reference/expressions.html#atom-identifiers
AttributeError: Bok instance has no attribute '_Bok__produktNetto'
The problem is that you named those members with two leading underscores, which makes them invisible under those names outside that class (see http://docs.python.org/tutorial/classes.html).
If you rename those fields with a single underscore in both places, it will work as you intend.

Categories