I've been cleaning up some code from a module I'm extending and I can't seem to find a way to Pythonify this code:
global_next_id = 1
class Obj:
def __init__(self):
global global_next_id
self.id = global_next_id
global_next_id += 1
This code uses a global id to keep track of instances of a class (I need the variable self.id internally as well, and it needs to be a number).
Can anyone suggest a way to Pythonify this code?
You could consider using a class attribute to provide a counter. Each instance needs only to ask for the next value. They each get something unique. Eg:
from itertools import count
class Obj(object):
_ids = count(0)
def __init__(self):
self.id = next(self._ids)
This should do the job:
class Obj:
_counter = 0
def __init__(self):
Obj._counter += 1
self.id = Obj._counter
Here is a way to count instances without descendant classes sharing the same id/count. A metaclass is used to create a separate id counter for each class.
Uses Python 3 syntax for Metaclasses.
import itertools
class InstanceCounterMeta(type):
""" Metaclass to make instance counter not share count with descendants
"""
def __init__(cls, name, bases, attrs):
super().__init__(name, bases, attrs)
cls._ids = itertools.count(1)
class InstanceCounter(object, metaclass=InstanceCounterMeta):
""" Mixin to add automatic ID generation
"""
def __init__(self):
self.id = next(self.__class__._ids)
I found the following solution:
class Obj:
counter = 0
def __init__(self):
type(self).counter += 1
def __del__(self):
type(self).counter -= 1
It's better to use type(self).counter instead of Obj.counter
Generator?
def get_next_id():
curr_id = 1
while True:
yield curr_id
curr_id += 1
class InstanceCounter(object):
# the instance counter
counter = 0
def __init__(self, val):
self.val = all
# incrementing every time an instance is created
InstanceCounter.counter += 1
def set_val(self, val):
self.val = val
def get_val(self, val):
return self.val
# accessing the instance counter should be done through a class method
#classmethod
def get_counter(cls):
return cls.counter
# See the instance counter as it increments as new instances are created
a=InstanceCounter(5)
print(a.get_counter())
b=InstanceCounter(7)
print(a.get_counter(), b.get_counter())
c=InstanceCounter(9)
print(a.get_counter(), b.get_counter(), c.get_counter())
You can use dir() function, which returns all properties and functions in the current script, to count the numbers of instances of a certain class.
len([i for i in dir() if isinstance(eval(i), ClassName)])
Related
Suppose I want to use macros in Scala 3 to count the number of places a certain method doSomething() was used in the code:
// Macros.scala
import scala.quoted.{Expr, Quotes}
object Macros {
private var count: Int = 0
inline def doSomething() = ${increment()}
private def increment()(using Quotes) =
count = count + 1
Expr("some result")
inline def callCount() = ${getCount()}
private def getCount()(using Quotes) =
Expr(count)
}
And I have an object that uses doSomething() a few times:
// Runner.scala
object Runner {
def run() =
Macros.doSomething()
Macros.doSomething()
Macros.doSomething()
}
And I want to show, at runtime, the call count:
// Main.scala
object Main {
def main(args: Array[String]): Unit =
println(Macros.callCount())
}
Depending on the order in which these macros were compiled, the main function will print either 0 or 3. If I could control this order, I would instruct the compiler to compile Main.scala last, so that I get the expected value 3. Is that possible?
No, there's no way to control it, and you just mustn't write that kind of code.
I have a case class for configuration parameters which is populated (using NO external library) before starting the actual application.
I pass this config object through out the application and in too many places.
Now the question is can this object be made global so I can refer it across the application as the values are going to be constant.
case class ConfigParam() extends Serializable {
var JobId: Int = 0
var jobName: String = null
var snapshotDate: Date = null
}
val configParam = ???
val ss = getSparkSession(configParam) //Method call...
Using ConfigParam as a global object could have bad implications for you. First of all, it will make harder to test any function which is using that global object.
Maybe you could just pass ConfigParam as an implicit argument?
For example, let's say you've got 3 functions:
def funA(name: String)(implicit configParam: ConfigParam): String = ???
def funB(number: Int)(implicit configParam: ConfigParam): String = ???
//you don't have to explicitily pass config param to funA or funB
def funC(name: String)(implicit configParam: ConfigParam): String = funA(name) + funB(100)
implicit val configParam = ??? //you need to initialise configParams as implicit val
funC("somename") //you can now just call funC without explicitly passing configParam
//it will be also passed to all function calls inside funC
//as long as they've got implicit parameter list with ConfigParam
Another solution could be to use some kind of dependency-injection framework, like guice.
Is the below Scala class is mutable or immutable?
I believe that its immutable as I can't edit the variables or access them once its created but whats making me doubt myself is the fact that it returns the current instance of a variable using its functions. It also does not have final in front of it which is further making me doubt myself.
class person(name:String, dob:String){
def getName = name
def getDob = dob
def display() = {
println("Name "+name+" dob: "+dob)
}
}
Thanks,
You have a misconception with the term Immutable:
I believe that its immutable as I can't edit the variables or access
them once its created
That's the definition of a private thing (method, variable, ...). Immutability refers to the fact that you cannot mutate state, that is, you can't change the value of something unless you create a new instance of it.
Let's see it with an example:
trait Foo{
def myMutableValue: Int
}
class Clazz extends Foo{
var myMutableValue = 1
def changeState(): Int = {
myMutableValue += 1
myMutableValue
}
}
val bar = new Clazz
bar.changeState() // myMutableValue = 2
bar.changeState() // myMutableValue = 3
bar.changeState() // myMutableValue = 4
bar.myMutableValue // myMutableValue = 4
With that example, in your instance of Clazz (bar) you're changing the state of a class attribute, in this case myMutableValue is changing its value every time I invoke changeState.
Please note that the class is public by default and changeState is also public and that doesn't means that is immutable.
Now, let's see an immutable approach:
trait Foo{
def myMutableValue: Int
}
class Clazz extends Foo{
val myMutableValue = 1
def changeState(): Int = myMutableValue + 1
}
val instance = new Clazz
instance.changeState() // myMutableValue = 2
instance.changeState() // myMutableValue = 2
instance.changeState() // myMutableValue = 2
instance.myMutableValue // 1
With this approach, every call to changeState will evaluate to 2, no matter how many times I call the function. That is, because we're dealing with an immutable value (val myMutableValue = 1). Every invocation of changeState will perform the evaluation and return a copy of that value. You're not modifying in any way the value of myMutableValue.
Please take a look to this and this.
Also, please take a look at your code, you have some errors:
By convention, class name should be capitalized (Person instead of person).
You don't need to reassign your class values with def (def getNameand def getDob). You can use class values as is.
Lastly:
It also does not have final in front of it which is further making me
doubt myself.
Again, you're talking about different things. final, as in Java, is a modifier to prevent your class to be extended. It doesn't relate in any way to immutability In adition, if you want to prevent mutability in your subclass you have to make all their members final (see this).
Since your example is coded in Scala you have all the tools that the language itself offers at your disposal (e.g. val, sealed, final)
Please note that I've used a trait to explain the possible use of def.
EDIT: about final modifier and immutability
Thanks to #Silvio Mayolo and #puhlen for the comments and clarification about final
I am trying to initialize a derived class from text file input. A simple example of what I am trying to do:
file.txt:
1
2
main.py:
class Base:
def __init__(self, val1):
self.val1 = val1
def input_from_text(cls, init_deque):
#return cls(init_deque.popleft())
class Derived(Base):
def __init__(self, val1, val2):
Base.__init__(self, val1)
self.val2 = val2
def input_from_text(cls, init_deque):
#initialize base and derived here and return derived
def main(argv=None):
initialized_derived = Derived.input_from_text(deque(open("file.txt")))
assert initialized_derived.val1 is 1
assert initialized_derived.val2 is 2
Is there a good way to do this? Basically looking for something similar to what you would find in C++ with:
//calls operator>>(Base) then operator>>(Derived)
cin >> initialized_derived;
This way each class is nicely encapsulated and the base/derived classes don't need to know anything about each other (excepting __init__ which knows the number of args base takes).
Just realized that I was going about this the wrong way. Simple fix is to do something like:
class Base:
def __init__(self):
pass
def input_from_text(self, init_deque):
self.val1 = init_deque.popleft()
class Derived(Base):
def __init__(self):
Base.__init__(self)
def input_from_text(self, init_deque):
Base.input_from_text(self, init_deque)
self.val2 = init_deque.popleft()
Search results so far have led me to believe this is impossible without either a non-primary constructor
class Foo { // NOT OK: 2 extra lines--doesn't leverage Scala's conciseness
private var _x = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
or sacrificing the name of the parameter in the primary constructor (making calls using named parameters ugly)
class Foo(private var _x: Int) { // OK: concise
def x = _x
}
val f = new Foo(_x = 123) // NOT OK: named parameter should be 'x' not '_x'
ideally, one could do something like this:
class Foo(private var x: Int) { // OK: concise
// make just the getter public
public x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
I know named parameters are a new thing in the Java world, so it's probably not that important to most, but coming from a language where named parameters are more popular (Python), this issue immediately pops up.
So my question is: is this possible? (probably not), and if not, why is such an (in my opinion) important use case left uncovered by the language design? By that, I mean that the code either has to sacrifice clean naming or concise definitions, which is a hallmark of Scala.
P.S. Consider the case where a public field needs suddenly to be made private, while keeping the getter public, in which case the developer has to change 1 line and add 3 lines to achieve the effect while keeping the interface identical:
class Foo(var x: Int) {} // no boilerplate
->
class Foo { // lots of boilerplate
private var _x: Int = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
Whether this is indeed a design flaw is rather debatable. One would consider that complicating the syntax to allow this particular use case is not worthwhile.
Also, Scala is after all a predominantly functional language, so the presence of vars in your program should not be that frequent, again raising the question if this particular use case needs to be handled in a special way.
However, it seems that a simple solution to your problem would be to use an apply method in the companion object:
class Foo private(private var _x: Int) {
def x = _x
}
object Foo {
def apply(x: Int): Foo = new Foo(x)
}
Usage:
val f = Foo(x = 3)
println(f.x)
LATER EDIT:
Here is a solution similar to what you originally requested, but that changes the naming a bit:
class Foo(initialX: Int) {
private var _x = initialX
def x = _x
}
Usage:
val f = new Foo(initialX = 3)
The concept you are trying to express, which is an object whose state is mutable from within the object and yet immutable from the perspective of other objects ... that would probably be expressed as an Akka actor within the context of an actor system. Outside the context of an actor system, it would seem to be a Java conception of what it means to be an object, transplanted to Scala.
import akka.actor.Actor
class Foo(var x: Int) extends Actor {
import Foo._
def receive = {
case WhatIsX => sender ! x
}
}
object Foo {
object WhatIsX
}
Not sure about earlier versions, but In Scala 3 it can easily be implemented like follows:
// class with no argument constructor
class Foo {
// prive field
private var _x: Int = 0
// public getter
def x: Int = _x
// public setter
def x_=(newValue: Int): Unit =
_x = newValue
//auxiliary constructor
def this(value: Int) =
this()
_x = value
}
Note
Any definition within the primary constructor makes the definition public, unless you prepend it with private modifier
Append _= after a method name with Unit return type to make it a setter
Prepending a constructor parameter neither with val nor with var, makes it private
Then it follows:
val noArgFoo = Foo() // no argument case
println(noArgFoo.x) // the public getter prints 0
val withArgFoo = Foo(5) // with argument case
println(withArgFoo.x) // the public getter prints 5
noArgFoo.x = 100 // use the public setter to update x value
println(noArgFoo.x) // the public getter prints 100
withArgFoo.x = 1000 // use the public setter to update x value
println(withArgFoo.x) // the public getter prints 1000
This solution is exactly what you asked; in a principled way and without any ad hoc workaround e.g. using companion objects and the apply method.