30.12.2010, 08:20
The number of built-in data structures Python has is a big advantage. Python not only offers more of them, but they're more lightweight to use in code since you don't have to pre-declare or initialize variables. I did a bunch of code conversion for another Python plugin, and the number of types available to you just make implementing common SA-MP stuff more elegant.
From adminspec.pwn:
By comparison here are the equivalent bits from my adminspec.py:
Instead of using two MAX_PLAYERS length arrays, the Python version combines them into one dictionary that holds another data structure called a tuple. A tuple is pretty much an immutable array. The nice thing about tuples is that you can create them on the fly and try to evaluate them in-line. So instead of
we can use
The underlined part in the Python version is the in-line tuple comparison. (playerid,ADMIN_SPEC_TYPE_PLAYER) is a tuple.
I don't know if that does a good job selling just how much simpler and cleaner Python scripts are, especially compared to Pawn, but once you're familiar with the language and know how to use the built-ins you're provided with, you can do more in Python with less time and less code than you can in Pawn.
From adminspec.pwn:
Код:
new gSpectateID[MAX_PLAYERS];
new gSpectateType[MAX_PLAYERS];
*snip*
public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
{
// IF ANYONE IS SPECTATING THIS PLAYER, WE'LL ALSO HAVE
// TO CHANGE THEIR INTERIOR ID TO MATCH
new x = 0;
while(x!=MAX_PLAYERS) {
if( IsPlayerConnected(x) && GetPlayerState(x) == PLAYER_STATE_SPECTATING &&
gSpectateID[x] == playerid && gSpectateType[x] == ADMIN_SPEC_TYPE_PLAYER )
{
SetPlayerInterior(x,newinteriorid);
}
x++;
}
}
*snip*
// end assignments from /specplayer
gSpectateID[playerid] = specplayerid;
gSpectateType[playerid] = ADMIN_SPEC_TYPE_PLAYER;
*snip*
// bit from /specoff where both arrays are set to null values
gSpectateID[playerid] = INVALID_PLAYER_ID;
gSpectateType[playerid] = ADMIN_SPEC_TYPE_NONE;
Код:
# the original gSpectateID and gSpectateType arrays have been combined
# into one dictionary of 2-tuples, (id,type)
gSpectate = {}
def OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid):
# IF ANYONE IS SPECTATING THIS PLAYER, WE'LL ALSO HAVE
# TO CHANGE THEIR INTERIOR ID TO MATCH
for x in range(0,MAX_PLAYERS):
if IsPlayerConnected(x) and GetPlayerState(x) == PLAYER_STATE_SPECTATING and\
gSpectate.has_key(x) and gSpectate[x] == (playerid,ADMIN_SPEC_TYPE_PLAYER):
SetPlayerInterior(x,newinteriorid)
*snip*
# same bit from /specplayer - now it's just one line
gSpectate[playerid] = (id,ADMIN_SPEC_TYPE_PLAYER)
*snip*
# same bit from /specoff - instead of setting items in two arrays to null values
# we just remove the entry entirely
gSpectate.pop(playerid)
Код:
if( IsPlayerConnected(x) && GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] == playerid && gSpectateType[x] == ADMIN_SPEC_TYPE_PLAYER )
Код:
if IsPlayerConnected(x) and GetPlayerState(x) == PLAYER_STATE_SPECTATING and\
gSpectate.has_key(x) and gSpectate[x] == (playerid,ADMIN_SPEC_TYPE_PLAYER):
SetPlayerInterior(x,newinteriorid)
I don't know if that does a good job selling just how much simpler and cleaner Python scripts are, especially compared to Pawn, but once you're familiar with the language and know how to use the built-ins you're provided with, you can do more in Python with less time and less code than you can in Pawn.


