Create and Initialize Instances of a Class with Sequential Names

Create and initialize instances of a class with sequential names

This should do the trick:

accounts = 100.times.collect { BankAccount.new(100) }

If you need to do something different for each account based on which one it is then:

accounts = 100.times.collect { |i| BankAccount.new(i) }

i represents each number in the collection being iterated over.

If you actually need to set the variable names using the data you can call eval().

accounts = 100.times.collect { |i| eval("B#{i} = BankAccount.new(100)") }

And now B1 through B100 should be set to the appropriate BankAccount instances.

Disclaimer:
I should say that this approach will be generally frowned upon. In this case you already have an array called accounts. All you need to do is index on it to get the corresponding bank account. accounts[50] for example instead of Ba50. In my years of ruby development I've found few places to use eval that made sense.

Can you initialise multiple instances of a class in one single line?

Create the Output objects in a list, and then you can iterate through the list:

outputs = [Output(layout={'border': '1px solid black'}) for _ in range(3)]

for i, out in enumerate(outputs, 1):
with out:
display(f"here is out{i}")

display(HBox(outputs))

How to initialize a listtype with consecutive values?

Use Enumerable.Range like:

List<Sample> samvalues = Enumerable.Range(1, 30)
.Select(r => new Sample {A = "a" + r, B = r})
.ToList();

Or

List<Sample> samvalues = Enumerable.Range(1, 30)
.Select(r => new Sample {A = String.Format("{0}{1}", "a", r), B = r})
.ToList();

How to initialize an object that requires __new__ and __init__

First, your sequence isn’t much of a type so far: calling append on it won’t preserve its indexed nature (let alone sort or slice assignment!). If you just want to make lists that look like this, just write a function that returns a list. Note that list itself behaves like such a function (it was one back in the Python 1 days!), so you can often still use it like a type.

So let’s talk just about d0. Leaving aside the question of whether deriving from int is a good idea (it’s at least less work than deriving from list properly!), you have the basic idea correct: you need __new__ for an immutable (base) type, because at __init__ time it’s too late to choose its value. So do so:

class d0(int):
def __new__(cls,val,i,parent):
return super().__new__(cls,val)

Note that this is a class method: there’s no instance yet, but we do need to know what class we’re instantiating (what if someone inherits from d0?). This is what attempt #1 got wrong: it thought the first argument was an instance to which to assign attributes.

Note also that we pass only one (other) argument up: int can’t use our ancillary data. (Nor can it ignore it: consider int('f',16).) Thus failed #2: it sent all the arguments up.

We can install our other attributes now, but the right thing to do is use __init__ to separate manufacturing an object from initializing it:

# d0 continued
def __init__(self,val,i,parent):
# super().__init__(val)
self.i=i; self.parent=parent

Note that all the arguments appear again, even val which we ignore. This is because calling a class involves only one argument list (cf. d0(elem,i,self)), so __new__ and __init__ have to share it. (It would therefore be formally correct to pass val to int.__init__, but what would it do with it? There’s no use in calling it at all since we know int is already completely set up.) Using #3 was painful because it didn’t follow this rule.

how to name and create multiple instances of a class in python?

If you print a list of something the list itself print's it's elements using repr(element)
:

class Card: 
def __init__(self, number, suit, trump='not the trump'):
self.number = number
self.suit = suit
self.trump = trump

def make_trump(self):
self.trump = 'the trump'

def remove_trump(self):
self.trump = 'not the trump'

def __str__(self):
return f'{self.number} of {self.suit}'

# provide the __repr__ method to be the same as str so iterables
# when printing this will not print the memory adress but the more
# meaningfull representation
def __repr__(self):
return str(self) # same as str

should do the trick

You can then simply

suits = ['spades', 'hearts', 'clubs', 'diamonds']
deck = []
for Suit in suits:
for i in range(13):
deck.append(Card(i, Suit)) # fix this

print(deck)

Output:

[0 of spades, 1 of spades, 2 of spades, 3 of spades, 4 of spades, 5 of spades, 
6 of spades, 7 of spades, 8 of spades, 9 of spades, 10 of spades, 11 of spades,
12 of spades, 0 of hearts, 1 of hearts, 2 of hearts, 3 of hearts, 4 of hearts,
5 of hearts, 6 of hearts, 7 of hearts, 8 of hearts, 9 of hearts, 10 of hearts,
11 of hearts, 12 of hearts, 0 of clubs, 1 of clubs, 2 of clubs, 3 of clubs, 4 of clubs,
5 of clubs, 6 of clubs, 7 of clubs, 8 of clubs, 9 of clubs, 10 of clubs, 11 of clubs,
12 of clubs, 0 of diamonds, 1 of diamonds, 2 of diamonds, 3 of diamonds, 4 of diamonds,
5 of diamonds, 6 of diamonds, 7 of diamonds, 8 of diamonds, 9 of diamonds, 10 of diamonds,
11 of diamonds, 12 of diamonds]

Static field initialization sequence in a class

The constant static variables are initialized before any non-static variables are initialized. The JLS, Section 12.4.2, states the initialization procedure for a class:


  1. Otherwise, record the fact that initialization of the Class object for C is in progress by the current thread, and release LC.
    Then, initialize the static fields of C which are constant variables (§4.12.4, §8.3.2, §9.3.1).

(other steps here)


  1. Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

So, INSTANCE is listed textually first, before list, map, and name. Why aren't all 3 still null? This is because name is initialized by a constant expression; it is a constant variable. It is initialized first, before INSTANCE, because it it a constant variable.

Note that you can move the line initializing INSTANCE after list and map, causing list and map to be initialized before INSTANCE.

When does the members of the class initialize?

You can analyze the question this way:

class Scratch {
public static void main(String[] args) {
A a = new A ("xyz");
}
}

class A{
public B b = new B();
private C c = new C(123);

public A (String a){
System.out.println("new A()");
}
}

class B {
public B() {
System.out.println("new B()");
}
}

class C {
public C(int i) {
System.out.println("new C()");
}
}

which executes giving the following output:

new B()
new C()
new A()

which matches wiith the answer of @Jakir Hossain.

So: inline fields initializers are executed before code in constructor, following the same order which they are declared in.

Instances of classes B and C are created on A's instance creation, before A's constructor is executed. This ordering (and fields' initialization) are guaranteed.

Initialisations in the class

Initializing instance variables directly does not initialize them before creating the object - it's just syntactic sugar that Java provides to save you another line in the constructor. For example, the following snippet:

public class MyClass {
int member = 7;
}

Is equivilant to

public class MyClass {
int member;

public MyClass() {
memeber = 7;
}
}


Related Topics



Leave a reply



Submit