Python - Inheritance - python

I'm not understanding any online documentation about how to make inheritance work.
I have this here:
import maya.cmds as cmds
class RigLegs():
def __init__(self, *args):
self.rigLegs()
def rigLegs(self):
self.items["side"] = "left"
self.lIK = cmds.duplicate(self.lJoints["hip"], n = self.getName("hip_IK"))
for i in self.lIK:
newName = i[0].replace("_JNT", "_IK")
cmds.rename(i, newName)
But it's complaining that there is no self.items - I have to inherit it from another class which is far too large to post here. Can anyone help me figure out how to do that? I've researched online and nothing makes any sense.
The other class is in a different file altogether.

To inherit from another class do:
class RigLegs(base_class_name):
An Example:
class base_class():
items = [1,2,3]
class pie(base_class):
def __init__(self):
print (self.items)
instance = pie()
You can read more in the Python Documentation
With imports:
file (apples.py)
class base():
items = [1,3,4]
file (main_file.py)
import apples
class pie(apples.base):
def __init__(self):
self.pies()
def pies(self):
print(self.items)
instance = pie()

In the class declaration: class RigLegs(), you should include all the classes you want to inherit from, such as in:
class RigLegs(Ancestor1, Ancestor2):
# Your code chere.
Don't forget that you still need to call the initialization logic of your ancestors.
def __init__(self):
super(RigLegs, self).__init__()

Related

How to Access variable and functions of any class in a different class in python

import copy
class Myclass0:
paperlist=[]
class Myclass1:
def copy_something(self):
Paper = Myclass0()
Flowers = ["Roses","Sunflower","Tulips","Marigold"]
Paper.paperlist = copy.copy(Flowers)
class Myclass3:
superlist = []
Paper = Myclass0()
print(Paper.paperlist)
superlist.append(paperlist[0])
I am getting a index out of range error on compiling.please help me finding a way to print paperlist of Myclass0 in Myclass3 using class Myclass1 Functions and attributes.You can change the class body but All the Classes should be used.
I am waiting for your valuable efforts.
Thank You
maybe this code snippet could help you understand it better:
class MyClass0:
def __init__(self):
# this is now an attribute of the instance (not the class)
self.paperlist = []
class MyClass1:
#staticmethod
def copy_something(paper):
# this is a static method (it doesnt rely on the Class (MyClass1) or an instance of it
flowers = ["Roses", "Sunflower", "Tulips", "Marigold"]
paper.paperlist = flowers
class Myclass3:
def __init__(self, paper):
# when an instance of this class is created an instance of MyClass0
# must pre passed to its constructor. It then prints out its paperlist
print(paper.paperlist)
paper = MyClass0()
MyClass1.copy_something(paper)
Myclass3(paper)

python method override with multiple inheritance and instancing

Here is my code - my base_file.py
class modify_file(object):
def modify_file_delete_obj():
print "modify file here"
def modify_file_add_attributes():
print "modify file here"
return ["data"]
class task_list(object):
modify_file_instance = modify_file() #problem part when accessing from project1.py
def check_topology():
data = modify_file_instance.modify_file_add_attributes()
#use this data further in this method
def check_particles():
print "check for particles"
project1.py file
import base_file as base_file
class project1(base_file.modify_file,base_file.task_list):
#overriding method of modify_file class
def modify_file_add_attributes(self):
print "different attributes to modify"
return ["different data"]
The idea is to run base_file.py for most projects and the project specific ones when required.
But when i run the method
"check_topology" from project1.py
the modify_file class is being derived from the base_file.py not project1.py
So the output is still ["data"] not ["different data"]
If you want to correctly use inheritance, define a base class Pet which provides a method to be overridden by a specific kind of pet.
class Pet(object):
def talk(self):
pass
class Cat(Pet):
def talk(self):
return "meow"
class Dog(Pet):
def talk(self):
return "woof"
pets = [Cat(), Dog(), Cat()]
for p in pets:
print(p.talk())
# Outputs
# meow
# woof
# meow
(I leave the issue of what Pet.talk should do, if anything, as a topic for another question.)
You are mixing up object composition with multiple inheritance.
The task_list class uses object composition when it creates an internal instance of the modify_file class. But there is a problem here in that you are creating it as a class attribute, which means it will be shared by all instances of task_list. It should instead be an instance attribute that is created in an __init__ method:
class task_list(object):
def __init__(self):
super(task_list, self).__init__()
self.modify_file_instance = modify_file()
def check_topology(self):
data = self.modify_file_instance.modify_file_add_attributes()
The project1 class uses multiple inheritance, when in fact it should use single inheritance. It is a kind of task_list, so it makes no sense for it to inherit modify_file as well. Instead, it should create it's own internal sub-class of modify_file - i.e. use object composition, just like task_list class does:
# custom modify_file sub-class to override methods
class project1_modify_file(base_file.modify_file):
def modify_file_add_attributes(self):
print "different attributes to modify"
return ["different data"]
class project1(base_file.task_list):
def __init__(self):
super(project1, self).__init__()
self.modify_file_instance = project1_modify_file()
Now you have a consistent interface. So when project1.check_topology() is called, it will in turn call task_list.check_topology() (by inheritance), which then accessses self.modify_file_instance (by composition):
>>> p = project1()
>>> p.check_topology()
different attributes to modify
In your dog class you're re-constructing an instance of cat, this instance (and the cat type) does not know they are inherited elsewhere by pets.
So you can naturally try:
class cat(object):
def meow(self):
self.sound = "meow"
return self.sound
class dog(object):
def woof(self):
return self.meow()
class pets(cat,dog):
def meow(self):
self.sound = "meow meow"
return self.sound
print(pets().woof())
Which still make no sense with those actual names, but you told they are fake names so it make be OK.

Python creating different objects in current Class

class Family:
def __init__(self, number_of_family_members):
self.members = self.create_members(number_of_family_members)
def create_members(self, number):
family_people = []
for i in range(number):
family_people.append(Human())
#family_people.append(self.Human())
return family_people
class Human:
def __init__(self):
self.exists = True
I plan on having Family Objects that will contain Human Objects. I am not sure if I am (1) correctly calling the method "create_members" (2) not sure how to initiate Humans
*I am currently learning about Objects so I wasn't sure if this was correct. Thanks!
What's the issue? Your code is fine. You can inspect it on the terminal to see what is happening. You can also simplify the initialization code.
class Family:
def __init__(self, number_of_family_members):
self.members = [Human()] * number_of_family_members
class Human:
def __init__(self):
self.exists = True
>>> f = Family(5)
>>> f.members
[<__main__.Human instance at 0x1102ca560>, <__main__.Human instance at 0x1102ca560>, <__main__.Human instance at 0x1102ca560>, <__main__.Human instance at 0x1102ca560>, <__main__.Human instance at 0x1102ca560>]

Creating subclass for wx.TextCtrl

I'm creating a subclass for the wx.TextCtrl in wxpython.
I want this class to add extra data to the wx.TextCtrl widgets similar as to the way extra data can be added to a ComboBox or ListBox.
Here's my code:
import wx
class ExtraDataForTxtCtrl(wx.TextCtrl):
def __init(self, ExtraTextData):
self.ExtraTextData=ExtraTextData
def getExtraTCData(self):
return self.ExtraTextData
def setExtraTCData(self, ExtraTextData):
self.ExtraTextData=ExtraTextData
My problem is that I'm new to python and have no idea how to implement this and if it is correct or not.
import wx
class ExtraDataForTxtCtrl(wx.TextCtrl):
def __init__(self,*args,**kwargs):
self.ExtraTextData=kwargs.pop("ExtraTextData")
wx.TextCtrl.__init__(self,*args,**kwargs)
def getExtraTCData(self):
return self.ExtraTextData
def setExtraTCData(self, ExtraTextData):
self.ExtraTextData=ExtraTextData
possibly a better solution would be to use set/getattr
class DataTxtCtrl(wx.TextCtrl):
def __init__(self,*args,**kwargs):
self.datadict = {}
self.ExtraTextData=kwargs.pop("ExtraTextData")
wx.TextCtrl.__init__(self,*args,**kwargs)
def __getattr__(self,attr):
return self.datadict[attr]
def __setattr__(self,attr,val):
self.datadict[attr]=val
then you can set many variables and use it like normal
a = wx.App(redirect=False)
f = wx.Dialog(None,-1,"Example")
te = DataTxtCtrl(f,-1,"some_default")
te.somevar = "hello"
te.someother = "world"
print te.somevar+" "+te.someothervar
f.ShowModal()
Instead of creating a subclass I just decided to create my own class which links an extra string value to wx.textCtrl widgets.
Thanks to all who contributed! :)
Heres my code:
class TextDataHolder:
def __init__(self, wxTextControl, data):
self.wxTextControl=wxTextControl
self.data=data
def setDataTxt(self,data):
self.wxTextControl=wxTextControl
self.data=data
def getDataTxt(self):
return self.data
Heres how I implemented it:
import wx, TextDataHolder
exampleCtrl=wx.TextCtrl(self, -1, "Hello")
exampleData=TextDataHolder.TextDataHolder(exampleCtrl,"Sup?")
print exampleData.getDataTxt() #prints 'Sup?'

How to access a class method from a property definition

I have a model where I want to use a class method to set the default of for a property:
class Organisation(db.Model):
name=db.StringProperty()
code=db.StringProperty(default=generate_code())
#classmethod
def generate_code(cls):
import random
codeChars='ABCDEF0123456789'
while True: # Make sure code is unique
code=random.choice(codeChars)+random.choice(codeChars)+\
random.choice(codeChars)+random.choice(codeChars)
if not cls.all().filter('code = ',code).get(keys_only=True):
return code
But I get a NameError:
NameError: name 'generate_code' is not defined
How can I access generate_code()?
As I said in a comment, I would use a classmethod to act as a factory and always create you entity through there. It keeps things simpler and no nasty hooks to get the behaviour you want.
Here is a quick example.
class Organisation(db.Model):
name=db.StringProperty()
code=db.StringProperty()
#classmethod
def generate_code(cls):
import random
codeChars='ABCDEF0123456789'
while True: # Make sure code is unique
code=random.choice(codeChars)+random.choice(codeChars)+\
random.choice(codeChars)+random.choice(codeChars)
if not cls.all().filter('code = ',code).get(keys_only=True):
return code
#classmethod
def make_organisation(cls,*args,**kwargs):
new_org = cls(*args,**kwargs)
new_org.code = cls.generate_code()
return new_org
import random
class Test(object):
def __new__(cls):
cls.my_attr = cls.get_code()
return super(Test, cls).__new__(cls)
#classmethod
def get_code(cls):
return random.randrange(10)
t = Test()
print t.my_attr
You need specify the class name: Organisation.generate_code()

Categories