Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
-
Tess
- Newbie
- Posts: 23
- Joined: Thu Aug 04, 2022 3:43 pm
- Projects: The Songbird Guild
- Organization: Yurisoft
- Github: wainwt2
- Discord: Tess#7782
-
Contact:
#1
Post
by Tess » Thu Oct 27, 2022 8:37 pm
I'm trying to make a class that can be iterated over like a list, but I'm not sure how to properly implement __iter__ and __next__.
Code: Select all
class Party():
"""A group of units that fight on the same team, either friend or foe."""
def __init__(self,*units):
"""Takes Unit instances and makes a list of them in the team variable"""
self.team = units if isinstance(units,list) else [units]
self.index = 0
def __call__(self):
"""Lets instances of this class be called directly to get the list of party members"""
return self.team
def __iter__(self):
"""Makes this class iterable"""
return self.team
def __next__(self):
"""Handles how the iterator moves through the class's party members"""
if self.index >= len(self.team):
raise StopIteration
else:
self.index += 1
return self.team[index-1]
###Class continues###
However, when I try to run it, I get the error message in the title.
From my understanding, RevertableList is a special Ren'Py list that works with rollback, but still has the properties of a normal list. If that's the case though, I'm not sure why python wouldn't see it as an iterable.
Last edited by
Tess on Fri Oct 28, 2022 8:14 pm, edited 2 times in total.
-
_ticlock_
- Veteran
- Posts: 391
- Joined: Mon Oct 26, 2020 5:41 pm
-
Contact:
#2
Post
by _ticlock_ » Thu Oct 27, 2022 11:57 pm
Tess wrote: ↑Thu Oct 27, 2022 8:37 pm
I'm trying to make a class that can be iterated over like a list, but I'm not sure how to properly implement __iter__ and __next__.
However, when I try to run it, I get the error message in the title.
From my understanding, RevertableList is a special Ren'Py list that works with rollback, but still has the properties of a normal list. If that's the case though, I'm not sure why python wouldn't see it as an iterable.
You need to return self:
Same for __call__ method
These lines are likely wrong
Code: Select all
def __init__(self,*units):
self.team = units if isinstance(units,list) else [units]
1) You either don't use
*unit but
unit.
Code: Select all
def __init__(self,units):
self.team = units if isinstance(units,list) else [units]
Code: Select all
$ party_1 = Party(unit)
$ party_2 = Party([unit,unit])
2) Or other logic
Code: Select all
def __init__(self,*units):
self.team = [unit for unit in units]
Code: Select all
$ party_1 = Party(unit)
$ party_2 = Party(unit,unit)
Warning: Note that renpy can't save
iterator objects.
-
Tess
- Newbie
- Posts: 23
- Joined: Thu Aug 04, 2022 3:43 pm
- Projects: The Songbird Guild
- Organization: Yurisoft
- Github: wainwt2
- Discord: Tess#7782
-
Contact:
#3
Post
by Tess » Fri Oct 28, 2022 11:35 am
I've been a bit confused on what *args actually creates. Using
is working great so far though!
However, when I change __iter__ and __call__ to return self rather than self.team, the error updates to "iter() returned non-iterator type Party"
-
_ticlock_
- Veteran
- Posts: 391
- Joined: Mon Oct 26, 2020 5:41 pm
-
Contact:
#4
Post
by _ticlock_ » Fri Oct 28, 2022 4:18 pm
Tess wrote: ↑Fri Oct 28, 2022 11:35 am
However, when I change __iter__ and __call__ to return self rather than self.team, the error updates to "iter() returned non-iterator type Party"
1) Not sure why. It seems like it does not see the
__next__ method in the class
Party. Check the indentation.
Works for this little test:
Code: Select all
init python:
class Party():
def __init__(self,*units):
self.team = [unit for unit in units]
self.index = 0
def __iter__(self):
self.index = 0
return self
def __next__(self):
if self.index >= len(self.team):
raise StopIteration
else:
self.index += 1
return self.team[self.index-1]
screen party_menu:
vbox:
for i in myclass:
add i
label start:
python:
a = [TextButton(f"Unit - {i}", action=Return(i)) for i in range(0,10)]
myclass = Party(*a)
call screen party_menu
"Selected : [_return]"
-
Ocelot
- Eileen-Class Veteran
- Posts: 1882
- Joined: Tue Aug 23, 2016 10:35 am
- Github: MiiNiPaa
- Discord: MiiNiPaa#4384
-
Contact:
#5
Post
by Ocelot » Fri Oct 28, 2022 4:40 pm
A question: which RenPy version do you use? Pyhon 2 and 3 define iterators differently.
< < insert Rick Cook quote here > >
-
Tess
- Newbie
- Posts: 23
- Joined: Thu Aug 04, 2022 3:43 pm
- Projects: The Songbird Guild
- Organization: Yurisoft
- Github: wainwt2
- Discord: Tess#7782
-
Contact:
#6
Post
by Tess » Fri Oct 28, 2022 8:14 pm
Oh yeah, I'm on Ren'Py 7.5. I haven't been able to use the game with 8 so far because pydub doesn't seem to mesh with it for some reason:
viewtopic.php?f=8&t=65523
I looked into it though, and realized I have to use next instead of __next__ in Python 2. Changed it to this and it worked perfectly:
Code: Select all
class Party():
"""A group of units that fight on the same team, either friend or foe."""
def __init__(self,*units):
"""Takes Unit instances and makes a list of them in the team variable"""
self.team = [unit for unit in units]
self.index = 0
def __iter__(self):
"""Makes this class iterable"""
self.index = 0
return self
def next(self):
"""Handles how the iterator moves through the class's party members"""
if self.index >= len(self.team):
raise StopIteration
else:
self.index += 1
return self.team[self.index-1]
Thank you so much for your help guys!
Users browsing this forum: Google [Bot]