So I have the following class object:
class Bond(object):
def __init__(self, Atom1=None, Atom2=None):
self.atoms = [Atom1, Atom2]
where Atom1 and Atom2 are mutable objects.
and I have:
>>> first_bond
Bond(Atom1, Atom2)
>>> second_bond
Bond(Atom1, Atom3)
>>> third_bond
Bond(Atom2, Atom1)
and also have:
>>> bonds
[first_bond, second_bond, third_bond]
If you realize, the first_bond and third_bond are the same since one is the reverse of the other, this is:
>>> first_bond == third_bond[::-1]
True
So my question is how can I implement a function or something that can filter only distinct objects, so that my final bonds is:
>>> bonds
[first_bond, second_bond]
I have read that maybe using __eq__ and __hash__ method would be a solution, and then using set(bonds). But since Atoms are mutable objects I don't know if this is kind of possible.
Related
How do you set/get the values of attributes of t given by x?
class Test:
def __init__(self):
self.attr1 = 1
self.attr2 = 2
t = Test()
x = "attr1"
There are built-in functions called getattr and setattr
getattr(object, attrname)
setattr(object, attrname, value)
In this case
x = getattr(t, 'attr1')
setattr(t, 'attr1', 21)
If you want to keep the logic hidden inside the class, you may prefer to use a generalized getter method like so:
class Test:
def __init__(self):
self.attr1 = 1
self.attr2 = 2
def get(self,varname):
return getattr(self,varname)
t = Test()
x = "attr1"
print ("Attribute value of {0} is {1}".format(x, t.get(x)))
Outputs:
Attribute value of attr1 is 1
Another apporach that could hide it even better would be using the magic method __getattribute__, but I kept getting an endless loop which I was unable to resolve when trying to get retrieve the attribute value inside that method.
Also note that you can alternatively use vars(). In the above example, you could exchange getattr(self,varname) by return vars(self)[varname], but getattrmight be preferable according to the answer to What is the difference between vars and setattr?.
Note: This answer is very outdated. It applies to Python 2 using the new module that was deprecated in 2008.
There is python built in functions setattr and getattr. Which can used to set and get the attribute of an class.
A brief example:
>>> from new import classobj
>>> obj = classobj('Test', (object,), {'attr1': int, 'attr2': int}) # Just created a class
>>> setattr(obj, 'attr1', 10)
>>> setattr(obj, 'attr2', 20)
>>> getattr(obj, 'attr1')
10
>>> getattr(obj, 'attr2')
20
I have a situation where I have 2 models, with the second model (B) being a subclass of the first (A), and also having a (different) 1-to-1 reference to another instance of same parent model (A). The objective is to have some special cases of A linked to other instances of A's in a new table, B's. For reasons I won't get into here, these need to be 2 different models (ie I can't add a nullable 1-to-1 reference field on A). This is illustrated below.
class A(models.Model):
name = models.CharField()
class B(A):
reference = models.OneToOneField(A)
However now when I try instantiate B with a reference to a different A, it doesn't work. Consider the following:
>>> a1 = A(name='a1')
>>> a1.save()
>>> b1 = B(name='b1', reference=a1)
>>> b1.save()
>>> b1.id
1
>>> b1.reference.id
1
Or alternatively:
>>> a1 = A(name='a1')
>>> a1.save()
>>> b1 = B(name='b1')
>>> b1.save()
>>> b1.reference = a1
>>> b1.save()
>>> b1.id
2
>>> b1.reference.id
2
Whereas what I would like here is for b1.id to equal 2 and b1.reference.id to equal 1 (referencing a1).
What is going on here? Why can't I have independent references to the base instance with the ptr_id and a different entry in the same table, in the reference field?
class Pizza(object):
radius = 2
#classmethod
def get_radius(self):
return self.radius
>>>print Pizza.get_radius is Pizza().get_radius
False
I think the result is True,because the classmedthod belongs to the class object.
When you instanciate Pizza you get a get_radius function which has a different id but points to the same code:
>>> id(Pizza().get_radius)
50027464
>>> id(Pizza.get_radius)
41275656
ok the refs are different but the contents are the same:
>>> Pizza.get_radius.__func__ is Pizza().get_radius.__func__
True
the function objects are the same and using == also yields True:
>>> Pizza().get_radius == Pizza.get_radius
True
So, like when comparing strings or integers, or whatever, it's better to avoid is because it's too much implementation dependent, with minimal benefits (except for the singletons like None)
>>> Pizza.get_radius()
2
>>> Pizza().get_radius
<bound method type.get_radius of <class 'Pizza'>>
When you type Pizza.get_radius(),you call the function and you get your result.
When you type Pizza().get_radius ,first of all you initiate a new Pizza object and you don't call the function really.
I have a list of objects, each of which has a list of things. I wish to create a list of the things held in all of the objects. Is there a more pythonic way of doing this?
class Holder(object):
def __init__(self, things):
self.things = things
holder_one= Holder([1, 2])
holder_two = Holder(['a', 'b'])
holders = [holder_one, holder_two]
all_things = []
for holder in holders:
for thing in holder.things:
all_things.append(thing)
print all_things
You could either:
Make Holder inherit from list then this becomes pretty trivial.
Use extend instead of append, which will save you an explicit loop:
all_things = []
for holder in holders:
all_things.extend(holder.things)
print all_things
since four days I'm trying to figure out how to follow a reference from one to another class, starting from the class which is beeing referenced. In SQL-Django there is a related_name to achieve this...
For example I have this class:
class MyClass(Document):
...
other_classes = ListField(ReferenceField(Other_Class))
and this one:
class Other_Class(Document):
...
Now I want to go from Other_Class to MyClass... Any ideas?
Thanks,
Ron
Here is a test case showing how to query it:
import unittest
from mongoengine import *
class StackOverFlowTest(unittest.TestCase):
def setUp(self):
conn = connect(db='mongoenginetest')
def test_one_two_many(self):
class MyClass(Document):
other_classes = ListField(ReferenceField("OtherClass"))
class OtherClass(Document):
text = StringField()
MyClass.drop_collection()
OtherClass.drop_collection()
o1 = OtherClass(text='one').save()
o2 = OtherClass(text='two').save()
m = MyClass(other_classes=[o1, o2]).save()
# Lookup MyClass that has o1 in its other_classes
self.assertEqual(m, MyClass.objects.get(other_classes=o1))
# Lookup MyClass where either o1 or o2 matches
self.assertEqual(m, MyClass.objects.get(other_classes__in=[o1, o2]))
The main question is do you need to store a list of references in the MyClass? It might be more efficient to store the relationship just on OtherClass..
Try this query:
oc = Other_Class()
MyClass.objects.find( other_classes__all = [oc.id] )
While thinking about my problem I came up with a solution.
I just add the ID of my referenced class to my model.
Here's an example:
class MyClass(Document):
...
other_classes = ListField(ReferenceField(Other_Class))
class Other_Class(Document):
myclass = ReferenceField(MyClass)
I'm not quite sure if this is the Mongo-way to do it but I'm pretty sure it works :)
Optionally you can omit the other_classes attribute in MyClass to avoid redundancy but then you need a query like this to get the "child" objects:
Other_Class.objects(myclass = myclass.id)