[英]Python error “unbound method must be called with instance as first argument”
It's high time I start using Classes. 现在是我开始使用类的时候了。 I have always found another way. 我总是找到另一种方式。 Yesterday I found exactly the code I need, but it's in a nice little Class and I can't figure out how to access it. 昨天我完全找到了我需要的代码,但是它在一个不错的小类中,我不知道如何访问它。 I've read all the tutorials and even similar solutions here. 我已经在这里阅读了所有教程以及类似的解决方案。 I just can't wrap my head around it. 我只是不能把头缠住它。 The only part I wrote, is "main()" which is the part that doesn't work. 我写的唯一部分是“ main()”,它是无效的部分。 I have re-written main a few dozen ways, and none of them work the way I expect them to work. 我已经将主要方法重新编写了几十种,但是它们都没有按照我期望的方式工作。
Thank you for your time, and patience. 感谢您的时间和耐心等待。
All credit goes to Nathan Adams - aka dinnerbone 所有功劳归纳森·亚当斯(Nathan Adams)-又名Dinnerbone
import socket
import struct
class MinecraftQuery:
MAGIC_PREFIX = '\xFE\xFD'
PACKET_TYPE_CHALLENGE = 9
PACKET_TYPE_QUERY = 0
HUMAN_READABLE_NAMES = dict(
game_id = "Game Name",
gametype = "Game Type",
motd = "Message of the Day",
hostname = "Server Address",
hostport = "Server Port",
map = "Main World Name",
maxplayers = "Maximum Players",
numplayers = "Players Online",
players = "List of Players",
plugins = "List of Plugins",
raw_plugins = "Raw Plugin Info",
software = "Server Software",
version = "Game Version",
)
def __init__(self, host, port, timeout=10, id=0, retries=2):
self.addr = (host, port)
self.id = id
self.id_packed = struct.pack('>l', id)
self.challenge_packed = struct.pack('>l', 0)
self.retries = 0
self.max_retries = retries
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.settimeout(timeout)
def send_raw(self, data):
self.socket.sendto(self.MAGIC_PREFIX + data, self.addr)
def send_packet(self, type, data=''):
self.send_raw(struct.pack('>B', type) + self.id_packed + self.challenge_packed + data)
def read_packet(self):
buff = self.socket.recvfrom(1460)[0]
type = struct.unpack('>B', buff[0])[0]
id = struct.unpack('>l', buff[1:5])[0]
return type, id, buff[5:]
def handshake(self, bypass_retries=False):
self.send_packet(self.PACKET_TYPE_CHALLENGE)
try:
type, id, buff = self.read_packet()
except:
if not bypass_retries:
self.retries += 1
if self.retries < self.max_retries:
self.handshake(bypass_retries=bypass_retries)
return
else:
raise
self.challenge = int(buff[:-1])
self.challenge_packed = struct.pack('>l', self.challenge)
def get_status(self):
if not hasattr(self, 'challenge'):
self.handshake()
self.send_packet(self.PACKET_TYPE_QUERY)
try:
type, id, buff = self.read_packet()
except:
self.handshake()
return self.get_status()
data = {}
data['motd'], data['gametype'], data['map'], data['numplayers'], data['maxplayers'], buff = buff.split('\x00', 5)
data['hostport'] = struct.unpack('<h', buff[:2])[0]
buff = buff[2:]
data['hostname'] = buff[:-1]
for key in ('numplayers', 'maxplayers'):
try:
data[key] = int(data[key])
except:
pass
return data
def get_rules(self):
if not hasattr(self, 'challenge'):
self.handshake()
self.send_packet(self.PACKET_TYPE_QUERY, self.id_packed)
try:
type, id, buff = self.read_packet()
except:
self.retries += 1
if self.retries < self.max_retries:
self.handshake(bypass_retries=True)
return self.get_rules()
else:
raise
data = {}
buff = buff[11:] # splitnum + 2 ints
items, players = buff.split('\x00\x00\x01player_\x00\x00') # Shamefully stole from https://github.com/barneygale/MCQuery
if items[:8] == 'hostname':
items = 'motd' + items[8:]
items = items.split('\x00')
data = dict(zip(items[::2], items[1::2]))
players = players[:-2]
if players:
data['players'] = players.split('\x00')
else:
data['players'] = []
for key in ('numplayers', 'maxplayers', 'hostport'):
try:
data[key] = int(data[key])
except:
pass
data['raw_plugins'] = data['plugins']
data['software'], data['plugins'] = self.parse_plugins(data['raw_plugins'])
return data
def parse_plugins(self, raw):
parts = raw.split(':', 1)
server = parts[0].strip()
plugins = []
if len(parts) == 2:
plugins = parts[1].split(';')
plugins = map(lambda s: s.strip(), plugins)
return server, plugins
def main():
check = MinecraftQuery.get_status('10.0.10.8',25565)
print check
main()
An unbound method is one that is not called with an instance of a class. 未绑定方法是未通过类的实例调用的方法。 Your error means that you are calling the method on the class rather than on an instance. 您的错误意味着您是在类而不是实例上调用方法。 So, you should first create an instance of the class and then call the method. 因此,您应该首先创建该类的实例,然后调用该方法。
I think it should be as follows. 我认为应该如下。 Try and see if it works. 尝试看看是否可行。
def main():
check = MinecraftQuery('10.0.10.8', 25565)
# It calls the __init__() method and constructs an object/instance of the class named 'MinecraftQuery'
# using the given arguments and associate it with the given identifier 'check'
check.get_status()
# Now, this invokes the get_status() method of the instance named 'check'.
print check
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.