I'm trying to figure out if there's a way to return one attribute of a nested object when the attribute is addressed using the 'dot' notation, but to return different attributes of that object when subsequent attributes are requested.
ex)
class MyAttributeClass:
def __init__(self, value):
self.value = value
from datetime.datetime import now
self.timestamp = now()
class MyOuterClass:
def __init__(self, value):
self._value = MyAttributeClass(value)
test = MyOuterClass(5)
test.value (should return test._value.value)
test.value.timestamp (should return test._value.timestamp)
Is there any way to accomplish this? I imagine, if there is one, it involves defining the __getattr__ method of MyOuterClass, but I've been searching around and I haven't found any way to do this. Is it just impossible? It's not a big deal if it can't be done, but I've wanted to do this many times and I'd just like to know if there's a way.
It seems obvious now, but inheritance was the answer. Defining attributes as instances of a custom class which inherits from the datatype I wanted for ordinary attribute access (i.e. object.attr) and giving this subclass the desired attributes for subsequent attribute requests (i.e. object.attr.subattr).
Related
In sympy, I have written the following code to create a custom subclass for the class Matrix:
from sympy import Matrix, symbols
class alsoMatrix(Matrix):
def __init__(self,name):
v0,v1,v2 = symbols(f'{name}[0:3]')
super().__init__([v0,v1,v2])
my_matrix = alsoMatrix('v')
But all I get is this error:
Data type not understood; expecting list of lists or lists of values.
And yet, I did put a list of values. In fact, even if I get rid of the 'symbols' and enter [0,0,0] into the super initializing function instead, I get the exact same error. What seems to be the problem here?
I think I figured out the problem. Sympy doesn't seem to use the __init__ method to create new instances, but rather the __new__ method, the syntax for which is slightly different. So I rewrote my code as the following:
from sympy import Matrix, symbols
class alsoMatrix(Matrix):
def __new__(cls,name):
v0,v1,v2 = symbols(f'{name}[0:3]')
return super(alsoMatrix,cls).__new__(cls,[v0,v1,v2])
my_matrix = alsoMatrix('v')
This seems to have done the trick.
I've been trying to figure out how to do this without manually defining a validation but without any success so far.
I have a StringField
class Foo private() extends MongoRecord[Foo] with ObjectIdKey[Foo] {
...
object externalId extends StringField(this, 255) {
// none of these seem to have any effect on validation whatsoever:
override def optional_? = false
override def required_? = true
override def defaultValueBox = Empty
}
...
}
Now when I call .validate on a Foo, it returns no errors:
val foo = Foo.createRecord
foo.validate match {
case Nil => foo.save
...
}
...and the document is saved into the (mongo) DB with no externalId.
So the question is: is there any way at all to have Lift automatically validate missing fields without me having to manually add stuff to validations?
EDIT: am I thinking too much in terms of the type of productivity that frameworks like Django and Rails provide out of the box? i.e. things like basic and very frequent validation without having to write anything but a few declarative attributes/flags. If yes, why has Lift opted to not provide this sort of stuff out of the box? Why would anybody not want .validate to automatically take into consideration all the def required_? = true/def optional_? = false fields?
As far as I'm aware, there isn't a way for you to validate a field without explicitly defining validations. The reason that optional_? and required_? don't provide validation is that it isn't always clear what logic to use, especially for non String fields. The required_? value itself is used by Crudify to determine whether to mark the field as required in the produced UI, but it's up to you to provide the proper logic to determine that the requirement is satisfied.
Validating the field can be as easy as
override def validations = super.validations :: valMinLen(1, "Required!")
Or see the answer to your other question here for how to create a generic Required trait.
I'm pretty sure the answer to this question is obviously "NO", since Django mixins are supposed to
inherit "object"s, but I can't find an alternative solution to my problem :(
To make the question as simple as possible,,,
views.py
class JSONResponseMixin(object):
def render_to_response(self, context):
"Returns a JSON response containing 'context' as payload"
return self.get_json_response(self.convert_context_to_json(context))
def get_json_response(self, content, **httpresponse_kwargs):
"Construct an `HttpResponse` object."
return http.HttpResponse(content,
content_type='application/json',
**httpresponse_kwargs)
def convert_context_to_json(self, context):
"Convert the context dictionary into a JSON object"
# Note: This is *EXTREMELY* naive; in reality, you'll need
# to do much more complex handling to ensure that arbitrary
# objects -- such as Django model instances or querysets
# -- can be serialized as JSON.
return json.dumps(context)
class HandlingAJAXPostMixin(JSONResponseMixin):
def post(self, request, *args, **kwargs):
.....
data = {'somedata': somedata}
return JSONResponseMixin.render_json_response(data)
class UserDetailView(HandlingAJAXPostMixin, DetailView):
model = MyUser
.....
So the problem I have is that, for multiple Views, I want to respond to their "post" request with the same
JSON Response. That is why I defined the HandlingAJAXPostMixin so that I could reuse it for
other Views. Since the HandlingAJAXPostMixin returns a JSON response,
it requires a render_json_response method, which is defined in the JSONResponseMixin.
This is the reason why I am making my HandlingAJAXPostMixin inherit the JSONResponseMixin, but this obviously seems wrong :(..
Any suggestions..?
Thanks!!!
It's perfectly valid for a mixin to inherit from another mixin - in fact, this is how most of Django's more advanced mixins are made.
However, the idea of mixins is that they are reusable parts that, together with other classes, build a complete, usable class. Right now, your JSONResponseMixin might as well be a separate class that you don't inherit from, or the methods might just be module-wide methods. It definitely works, there's nothing wrong with it, but that's not the idea of a mixin.
If you look at Django's BaseDetailView, you see the following get() method:
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
get_object() and get_context_data() are defined in the subclasses of BaseDetailView, but render_to_response() isn't. It's okay for mixins to rely on methods that it's superclasses don't define, this allows different classes that inherit from BaseDetailView to supply their own implementation of render_to_response(). Right now, in Django, there's only one subclass, though.
However, logic is delegated as much as possible to those small, reusable methods that the mixins supply. That's what you want to aim for. If/else logic is avoided as much as possible - the most advanced logic in Django's default views is:
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
That's why very similar views, like CreateView and UpdateView are in fact two separate views, while they could easily be a single view with some additional if/else logic. The only difference is that CreateView does self.object = None, while UpdateView does self.object = self.get_object().
Right now you are using a DetailView that defines a get() method that returns the result of self.render_to_response(). However, you override render_to_response() to return a JSON response instead of a template-based HTML response. You're using a mixin that you don't what to use (SingleObjectTemplateResponseMixin) and then override it's behavior to do something that you don't want to do either, just to get the view doing what you want it to do. A better idea would be to write an alternative for DetailView who's only job is to supply a JSON response based on a single object. To do this, I would create a SingleObjectJSONResponseMixin, similar to the SingleObjectTemplateResponseMixin, and create a class JSONDetailView that combines all needed mixins into a single object:
class SingleObjectJSONResponseMixin(object):
def to_json(context):
return json.dumps(context)
def render_to_response(context, **httpresponse_kwargs):
return HttpResponse(self.to_json(context),
context_type='application/json',
**httpresponse_kwargs)
class BaseJSONDetailView(SingleObjectMixin, View):
# if you want to do the same for get, inherit just from BaseDetailView
def post(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return render_to_response(context)
class JSONDetailView(SingleObjectJSONResponseMixin, BaseJSONDetailView):
"""
Return JSON detail data of a single object.
"""
Notice that this is almost exactly the same as the BaseDetailView and the SingleObjectTemplateResponseMixin provided by Django. The difference is that you define a post() method and that the rendering is much more simple with just a conversion to JSON of the context data, not a complete template rendering. However, logic is deliberately kept simple as much as possible, and methods that don't depend on each other are separated as much as possible. This way, SingleObjectJSONResponseMixin can e.g. be mixed with BaseUpdateView to easily create an AJAX/JSON-based UpdateView. Subclasses can easily override the different parts of the mixins, like overriding to_json() to supply a certain data structure. Rendering logic is where it belongs (in render_to_response()).
Now all you need to do to create a specific JSONDetailView is to subclass and define which model to use:
class UserJSONDetailView(JSONDetailView):
model = MyUser
I would like to write a subclass of pandas.core.index.Index. I'm following the guide to subclassing ndarrays which can be found in the numpy documentation. Here's my code:
import numpy as np
import pandas as pd
class InfoIndex(pd.core.index.Index):
def __new__(subtype, data, info=None):
# Create the ndarray instance of our type, given the usual
# ndarray input arguments. This will call the standard
# ndarray constructor, but return an object of our type.
# It also triggers a call to InfoArray.__array_finalize__
obj = pd.core.index.Index.__new__(subtype, data)
# set the new 'info' attribute to the value passed
obj.info = info
# Finally, we must return the newly created object:
return obj
However, it doesn't work; I only get a Index object:
In [2]: I = InfoIndex((3,))
In [3]: I
Out[3]: Int64Index([3])
What am I doing wrong?
Index constructor tries to be clever when the inputs are special (all ints or datetimes for example) and skips to calls to view at the end. So you need to put that in explicitly:
In [150]: class InfoIndex(pd.Index):
.....: def __new__(cls, data, info=None):
.....: obj = pd.Index.__new__(cls, data)
.....: obj.info = info
.....: obj = obj.view(cls)
.....: return obj
.....:
In [151]: I = InfoIndex((3,))
In [152]: I
Out[152]: InfoIndex([3])
Caveat emptor: be careful subclassing pandas objects as many methods will explicitly return Index as opposed to the subclass. And there are also features in sub-classes of Index that you'll lose if you're not careful.
If you implement the __array_finalize__ method you can ensure that metadata is preserved in many operations. For some index methods you'll need to provide implementations in your subclass. See http://docs.scipy.org/doc/numpy/user/basics.subclassing.html for a bit more help
To expand on the previous answers. You can also preserve most index methods, if you use the _constructor property and set _infer_as_myclass = True.
I've been practicing some Ruby meta-programming recently, and was wondering about assigning anonymous classes to constants.
In Ruby, it is possible to create an anonymous class as follows:
anonymous_class = Class.new # => #<Class:0x007f9c5afb21d0>
New instances of this class can be created:
an_instance = anonymous_class.new # => #<#<Class:0x007f9c5afb21d0>:0x007f9c5afb0330>
Now, when the anonymous class is assigned to a constant, the class now has a proper name:
Foo = anonymous_class # => Foo
And the previously created instance is now also an instance of that class:
an_instance # => #<Foo:0x007f9c5afb0330>
My question: Is there a hook method for the moment when an anonymous class is assigned to a constant?
There are many hooks methods in Ruby, but I couldn't find this one.
Let's take a look at how constant assignment works internally. The code that follows is extracted from a source tarball of ruby-1.9.3-p0. First we look at the definition of the VM instruction setconstant (which is used to assign constants):
# /insns.def, line 239
DEFINE_INSN
setconstant
(ID id)
(VALUE val, VALUE cbase)
()
{
vm_check_if_namespace(cbase);
rb_const_set(cbase, id, val);
INC_VM_STATE_VERSION();
}
No chance to place a hook in vm_check_if_namespace or INC_VM_STATE_VERSION here. So we look at rb_const_set (variable.c:1886), the function that is called everytime a constant is assigned:
# /variable.c, line 1886
void
rb_const_set(VALUE klass, ID id, VALUE val)
{
rb_const_entry_t *ce;
VALUE visibility = CONST_PUBLIC;
# ...
check_before_mod_set(klass, id, val, "constant");
if (!RCLASS_CONST_TBL(klass)) {
RCLASS_CONST_TBL(klass) = st_init_numtable();
}
else {
# [snip], won't be called on first assignment
}
rb_vm_change_state();
ce = ALLOC(rb_const_entry_t);
ce->flag = (rb_const_flag_t)visibility;
ce->value = val;
st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)ce);
}
I removed all the code that was not even called the first time a constant was assigned inside a module. I then looked into all the functions called by this one and didn't find a single point where we could place a hook from Ruby code. This means the hard truth is, unless I missed something, that there is no way to hook a constant assignment (at least in MRI).
Update
To clarify: The anonymous class does not magically get a new name as soon as it is assigned (as noted correctly in Andrew's answer). Rather, the constant name along with the object ID of the class is stored in Ruby's internal constant lookup table. If, after that, the name of the class is requested, it can now be resolved to a proper name (and not just Class:0xXXXXXXXX...).
So the best you can do to react to this assignment is to check the name of the class in a loop of a background worker thread until it is non-nil (which is a huge waste of resources, IMHO).
Anonymous classes don't actually get their name when they're assigned to a constant. They actually get it when they're next asked what their name is.
I'll try to find a reference for this. Edit: Can't find one, sorry.