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.