@@ -238,6 +238,28 @@ def __new__(cls, name, bases, attrs):
238238 return obj
239239
240240
241+ class _predicatedescriptor (property ):
242+ """
243+ A property that behaves as a class method if accessed via a class
244+ >>> class A:
245+ ... foo = False
246+ ... @_predicatedescriptor
247+ ... def is_foo(self):
248+ ... return self.foo
249+ ...
250+ >>> a = A()
251+ >>> a.is_foo
252+ False
253+ >>> A.is_foo(a)
254+ False
255+ """
256+ def __get__ (self , instance , objtype = None ):
257+ if instance is None :
258+ return self .fget
259+ else :
260+ return super ().__get__ (instance , objtype )
261+
262+
241263class Variable (Reprable , metaclass = VariableMeta ):
242264 """
243265 The base class for variable descriptors contains the variable's
@@ -357,6 +379,22 @@ def is_primitive(cls, var=None):
357379 to_check = cls if var is None else type (var )
358380 return issubclass (to_check , (DiscreteVariable , ContinuousVariable ))
359381
382+ @_predicatedescriptor
383+ def is_discrete (self ):
384+ return isinstance (self , DiscreteVariable )
385+
386+ @_predicatedescriptor
387+ def is_continuous (self ):
388+ return isinstance (self , ContinuousVariable )
389+
390+ @_predicatedescriptor
391+ def is_string (self ):
392+ return isinstance (self , StringVariable )
393+
394+ @_predicatedescriptor
395+ def is_time (self ):
396+ return isinstance (self , TimeVariable )
397+
360398 def repr_val (self , val ):
361399 """
362400 Return a textual representation of variable's value `val`. Argument
@@ -430,6 +468,9 @@ def copy(self, compute_value):
430468 return var
431469
432470
471+ del _predicatedescriptor
472+
473+
433474class ContinuousVariable (Variable ):
434475 """
435476 Descriptor for continuous variables.
@@ -1011,34 +1052,3 @@ def to_val(self, s):
10111052 return self .parse (s )
10121053 else :
10131054 return super ().to_val (s )
1014-
1015-
1016- class _TypeIndicatorDescriptor :
1017- """
1018- Descriptor that can be used on classes and on instances.
1019-
1020- On an instance, the descriptor is used as a property of a variable,
1021- e.g. `var.is_discrete`.
1022-
1023- As a class attribute, the descriptor returns a predicate that can
1024- be called as `Variable.is_discrete(var)` or, for a more common use,
1025- `filter(Variable.is_discrete, domain)`.
1026- """
1027- def __init__ (self , atype ):
1028- def __check_type (instance ):
1029- return isinstance (instance , atype )
1030-
1031- self .check_type = __check_type
1032-
1033- def __get__ (self , instance , owner ):
1034- if instance is not None :
1035- return self .check_type (instance )
1036- else :
1037- return self .check_type
1038-
1039- # These properties of Variable require its subclasses, hence they have to
1040- # inserted into the class later.
1041- Variable .is_discrete = _TypeIndicatorDescriptor (DiscreteVariable )
1042- Variable .is_continuous = _TypeIndicatorDescriptor (ContinuousVariable )
1043- Variable .is_string = _TypeIndicatorDescriptor (StringVariable )
1044- Variable .is_time = _TypeIndicatorDescriptor (TimeVariable )
0 commit comments