I am currently trying to abstract/default some behaviour away. All children define some constants differently and I want to reference said variable in their parent class. My attempt looks something like this:
class Mother():
a= True
#staticmethod
def something():
return Mother.a
class Child(Mother):
a = False
print(Mother.something())
print(Child.something())
Mother.something() obviously produces True, but Child.something() should produce False.
This doesn't work as I guess in inheritance in Python you don't override the variables but just hides them outside of vision?
In the Child class, when something is called, Mother.a is still valid, you're referring to the parent Mother class (defined at Childs class declaration). Python has another builtin called classmethod for your use case:
class Mother():
a = True
#classmethod
def something(cls):
return cls.a
class Child(Mother): # Mother.a gets defined here
a = False
print(Mother.something()) # True
print(Child.something()) # False
From the docs:
Class methods are different than C++ or Java static methods. If you want those, see staticmethod().
#classmethods define cls (by convention, the variable doesn't have to be called cls) as the first argument, just like instance methods would receive self as their first argument. cls refers to the class that the method is being called on.
I'd recommend this video for a great introduction on best practices for classes and how/where to use all the special decorators/syntax in python.
Since you mentioned abstract classes, you may be interested in the abc module as well.
Related
I'm wondering if I have:
class A(object):
def __init__(self):
self.attribute = 1
self._member = 2
def _get_member(self):
return self._member
def _set_member(self, member):
self._member = member
member = property(_get_member, _set_member)
class B(object):
def __init__(self):
self._member = A()
def _get_a_member(self):
return self._member.member
def _set_a_member(self, member):
self._member.member = member
member = property(_get_a_member, _set_a_member)
Can I somehow avoid to write get/setters for A.member, and simply refer to the attribute or property of the A object?
Where the get/setters do logic, its of course needed, but if I simply wan't to expose the member/attributes of a member attribute, then writing get/setters seems like overhead.
I think even if I could write the get/setters inline that would help?
I find the question a bit unclear, however I try to explain some context.
Where the get/setters do logic, its of course needed, but if I simply wan't to expose the member/attributes of a member attribute
If there is no logic in getter/setters, then there is no need to define the attribute as a property, but the attribute can be used directly (in any context).
So
class A(object):
def __init__(self):
self.attribute = 1
self.member = 2
class B(object):
def __init__(self):
self.member = A()
B().member.member # returns 2
B().member.member = 10
In some languages, it's considered good practice to abstract instance properties with getter/setter methods, That's not necessarily the case in Python.
Python properties are useful when you'd need more control over the attribute, for example:
when there is logic (validation, etc.)
to define a readonly attribute (so only providing a getter without a setter)
Update (after the comment)
properties are not necessarily a tool to "hide" some internal implementation. Hiding in Python is a bit different than say in Java, due to very dynamic nature of Python language. It's always possible to introspect and even change objects on the fly, you can add new attributes (even methods) to objects on runtime:
b = B()
b.foo = 4 # define a new attribute on runtime
b.foo # returns 4
So Python developers rely more on conventions to hint their intentions of abstractions.
About the polymorphic members, I think it's most natural for Python classes to just share an interface, that's what's meant by Duck typing. So as long as your next implementation of A supports the same interface (provides the same methods for callers), it should not be any issue to change its implementation.
So this is what I came up with - use a method to generate the properties, with the assumption that the obj has an attribute of _member:
def generate_cls_a_property(name):
"""Small helper method for generating a 'dumb' property for the A object"""
def getter(obj):
return getattr(obj._member, name)
def setter(obj, new_value):
setattr(obj._member, name, new_value)
return property(getter, setter)
This allows me to add properties like so:
class B(object):
def __init__(self):
self._member = A()
member = generate_cls_a_property('member') # generates a dumb/pass-through property
I'll accept my own, unless someone tops it within a week.. :)
I have a couple of child classes that I want to use but they both inherit a method from their parent that doesn't quite behave the way I need it to.
class ParentClass():
def __init__(self, value):
self.value = value
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
def other_parent(self):
print("I do other useful things my children inherit")
class Child1(ParentClass):
def __init__(self, value, new_value1):
super(Child1, self).__init__(value)
self.new_value1 = new_value1
def other_child1(self):
print("I do useful child things")
class Child2(ParentClass):
def __init__(self, value, new_value2):
super(Child2, self).__init__(value)
self.new_value2 = new_value2
def other_child2(self):
print("I do other useful child things")
I want to overwrite annoying_funct() as something like this:
def annoying_funct():
print("I behave the way I am needed to and print {0}".format(self.value))
ParentClass, Child1 and Child2 are from a very complex library (scikit-learn), so I want to keep all of my wrappers as thin as possible. What would be the cleanest/most pythonic way of getting the functionality of my two child classes while altering the parent class as needed?
My thoughts so far:
Create a new class that inherits from the parent which overwrites the function I don't like and then make wrapper classes for the children that inherit from the new class and the child classes.
class NewParentClass(ParentClass):
def annoying_funct(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(NewParentClass, Child1):
pass
class NewChild2(NewParentClass, Child2):
pass
My areas of confusion:
Is this the correct approach? It seems a little weird and klugy. Is there a cleaner way of doing this?
Is the syntax used for the two child classes correct? It runs for me, but it seems a little weird having them do nothing but inherit and pass.
Is having my new parent inherit from the previous parent the correct way of doing this? The code runs for the children without the inheritance between parentClass and newParentClass (eg. def newParentClass():), but if someone tried to make an instance of newParentClass() the function wouldn't work because it uses attributes not present in that class (value). Is that ok if I assume the class will never be used?
There are a couple of ways to do what you ask.
Create a new class inheriting from the parent class, then use it as new parent class.
The only drawback for this solution is that the when you provide the new parent or child class to functions requiring the original Parent class might not work since they might use annoying_funct and rely on an annoying behavior.
class NewParentClass:
def annoying_funct(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(NewParentClass):
pass
class NewChild2(NewParentClass):
pass
Manipulate the existing Parent class
This is the solution I would like to use since it destroys the annoying_funct completely by replacing it with a well behaving one, buy again, other methods and functions requiring the former annoying_funct might fail. The good side is, you don't need to create another parent class and children, so your code will be much more elegant.
class ParentClass():
...
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
...
def well_behaving_func(s):
print("Good")
# Dynamically change the class method
ParentClass.annoying_func = well_behaving_func
class Child1(Parent):
pass
class Child2(Parent):
pass
c = Child1()
c.annoying_funct() # prints 'Good'
Add a well behaving new method to parent class before inheriting from it.
If you want to maintain the current behavior and don't want your existing code or packages dependent on the parent class break, you certainly should not overwrite the annoying_funct in the parent class. So you should define a well behaving function and use it in child classes.
class ParentClass():
...
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
...
def well_behaving_func(s):
print("Good")
# Dynamically change the class method
ParentClass.well_behaving_func = well_behaving_func
class Child1(Parent):
pass
class Child2(Parent):
pass
c = Child1()
# use 'well_behaving_func', not the annoying one
c.well_behaving_func() # prints 'Good'
What I ended up doing was using the concept of a mixin to add my new functionality to the child classes. The resulting code was as follows:
class AnnoyMixin:
def well_behaving_func(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(AnnoyMixin, Child1):
def annoying_funct(self):
return well_behaving_func(self)
class NewChild2(AnnoyMixin, Child2):
def annoying_funct(self):
return well_behaving_func(self)
Functionally, this mostly behaves the same as the code I had proposed in my question, but the modifications help with readability. First, by naming the new parent as a "Mixin" it makes it clear that this class is not designed to stand on its own, but rather is intended to add functionality to another class. Because of this, AnnoyMixin doesn't need to inherit from ParentClass, simplifying inheritance for the NewChild classes.
Second, rather than overwriting annoying_funct in AnnoyMixin, we create the new function well_behaving_func. It is then the NewChild classes job to overwrite annoying_funct by calling well_behaving_func. Functionally, this works more or less the same as if the AnnoyMixin had over written annoying_funct, but this way, it is clearer to those reading the code that annoying_funct is being overwritten in the NewChild classes.
In one of my classes, I am printing data from another class that is yet to be initialized.I only want to print that data once the class has been initialized.Is there any way check if the class has been instantiated?
Two functions that return true if you pass an undeclared class, and false if it is instantiated:
import inspect
inspect.isclass(myclass)
or
isinstance(myclass, type)
In general, if it's not a type (i.e. undeclared class), it's an instantiated type.
Simply add a variable into the class to be made, like this:
class tobeinitiated():
initiated=False
def __init__(self):
global initiated
tobeinitiated.initiated = True
Then, where you need the information:
global initiated #(if in class)
if tobeinitiated.initiated:
#do the stuff you need to do
Hope this helps. :)
You can add a counter of instances in the constructor for example.
I have a class that has a basic method, and subclasses that have the same base functionality, but additional behaviour, which can be implemented with decorators.
class cls_with_basic_method:
#if...exec("#decoratorA")
#if...exec("#decoratorB")
#...
def basic_method(arg):
#...
return arg
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
#...
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
#...
#...
It seems the quickest solution would be if I were able to execute the particular decorator as the subclass method is called, but can't think of a way of expressing it in python. Can this easily be done?
A decorated function or method is usually a different object than the function or method it decorates [*] - so, you can just wrap the original class' method in an explict way. This is rather straightforawrd, and rather boring - but it will work if you need to decorate just a few methods of the sub-classes:
class cls_with_basic_method:
def basic_method(arg):
#...
return arg
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
basic_method = decoratorA(cls_with_basic_method.basic_method)
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
basic_method = decoratorB(cls_with_basic_method.basic_method)
The only special thing done there is use the decorators with the syntax of regular function calls instead of usign the "#..." syntax - this way they can be used inside the expressions.
This method is further boring due to you have to hardcode the superclass name within the class body at each decoration, since you can't use super from the class body, just from inside methods.
[*] Although some decorators just add metadata to the callable object they decorate and return the object itself - this approach won't work for such decorators, as they will affect the method in the superclass as well.
Now, taking your problem further - what you want is just to wrap arbitrary methods on the superclass when they are called on the subclasses. That can be done more or less automatically if you override the class__getattribute__ - you then could create a class hierarchy with an special "decorator" attribute that would be called for each method call - more or less like this:
class cls_with_basic_method:
_auto_decorate = set(("basic_method", ...))
_decorator = lambda x: x # NOP decorator
def basic_method(arg):
#...
return arg
def __getattribute__(self, attrname):
attr = object.__getattribute__(self, attr)
# shortcircuit non-method retrievelas as fast as possible:
if not attrname in __class__._auto_decorate not callable(attr):
return attr
return self.__class__._decorator(attr)
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
_decorator = decoratorA
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
_decorator = decoratorB
Of course, if you need different decorators for different methods, just change the code in __getattribute__ accordingly - the easiest way would be to make the _decorator attribute be a dictionary instead of pointing to a simple function.
(on a side note: the __class__ magic variable, when used inside a method, is a Python 3 thing: it automatically contains a reference to the class it is defined in (in this case, cls_with_basic_method).
This approach will redecorate the method on each call - it is not as much overhead as it seems to be - Python's default method retrieval mechanism itself is similarly complicated - but if you prefer to decorate the methods at class creation instead, tehn you can use a similar mechanism in a metaclass instead of relying on __getattribute__.
from itertools import chain
class AutoDecorate(type):
def __new__(metacls, name, bases, dct):
if "_decorator" not in dct:
dct["_decorator"] = lambda x: x # NOP decorator
all_bases = list(chain(base.__mro__ for base in bases))
for base in all_bases:
if not "_auto_decorate" in base.__dict__:
continue
for method_name in base.auto_decorate:
if method_name not in dct:
dct[method_name] = dct["_decorator"](getattr(base, method_name))
return super().__new__(name, bases, dct)
class cls_with_basic_method(metaclass=AutoDecorate):
_auto_decorate = set(("basic_method", ...))
def basic_method(arg):
#...
return arg
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
_decorator = decoratorA
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
_decorator = decoratorB
This is actually simpler than it might look: Upon creating a new class on the hierarchy, it just searches all superclasses for those which have the _auto_decorate attribute - and then it fetches the methods in that list, and decorate them with the decorator in the _decorator attribute of the class being created.
From what you are asking, I'd say you are dealing with a project where you need an "aspect oriented programing" approach. There are several Python libraries that can provide that functionality - maybe you should take a look at that. If you think so, search for modules that can provide appropriate Python aspect oriented capabilities and use those.
I'm still learning and like to build things that I will eventually be doing on a regular basis in the future, to give me a better understanding on how x does this or y does that.
I haven't learned much about how classes work entirely yet, but I set up a call that will go through multiple classes.
getattr(monster, monster_class.str().lower())(1)
Which calls this:
class monster:
def vampire(x):
monster_loot = {'Gold':75, 'Sword':50.3, 'Good Sword':40.5, 'Blood':100.0, 'Ore':.05}
if x == 1:
loot_table.all_loot(monster_loot)
Which in turn calls this...
class loot_table:
def all_loot(monster_loot):
loot = ['Gold', 'Sword', 'Good Sword', 'Ore']
loot_dropped = {}
for i in monster_loot:
if i in loot:
loot_dropped[i] = monster_loot[i]
drop_chance.chance(loot_dropped)
And then, finally, gets to the last class.
class drop_chance:
def chance(loot_list):
loot_gained = []
for i in loot_list:
x = random.uniform(0.0,100.0)
if loot_list[i] >= x:
loot_gained.append(i)
return loot_gained
And it all works, except it's not returning loot_gained. I'm assuming it's just being returned to the loot_table class and I have no idea how to bypass it all the way back down to the first line posted. Could I get some insight?
Keep using return.
def foo():
return bar()
def bar():
return baz()
def baz():
return 42
print foo()
I haven't learned much about how classes work entirely yet...
Rather informally, a class definition is a description of the object of that class (a.k.a. instance of the class) that is to be created in future. The class definition contains the code (definitions of the methods). The object (the class instance) basically contains the data. The method is a kind of function that can take arguments and that is capable to manipulate the object's data.
This way, classes should represent the behaviour of the real-world objects, the class instances simulate existence of the real-world objects. The methods represent actions that the object apply on themselves.
From that point of view, a class identifier should be a noun that describes category of objects of the class. A class instance identifier should also be a noun that names the object. A method identifier is usually a verb that describes the action.
In your case, at least the class drop_chance: is suspicious at least because of naming it this way.
If you want to print something reasonable about the object--say using the print(monster)--then define the __str__() method of the class -- see the doc.