首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python类和另一个函数中的对象

Python类和另一个函数中的对象
EN

Stack Overflow用户
提问于 2020-11-17 12:10:06
回答 1查看 117关注 0票数 0

我正在学习如何在Python代码中使用类和对象。我完全被假设是乞丐类的事实所淹没,我得到了这样的任务,如果这样的事情:

类名是IPAdress,在那里我需要属性IP、主机名、ASN和ISP。此外,它还有一种创建类似打印的方法:

代码语言:javascript
复制
IP: 85.76.129.254
Hostname: 85-76-129-254-nat.elisa-mobile.fi
ASN: 719
ISP: Elisa Mobile

方法可以命名为PrintDetails。

一旦类准备就绪,我想在我的Osio9函数中使用它,如下所示

  1. 函数要求用户输入IP、主机名、ASN和ISP。对象是根据此information.
  2. Object被添加到列表(最初为空)中创建的,在询问该用户是否希望创建新IP (如果回答是->重复上述过程(请求输入))之后,使用PrintDetails -method
  3. 打印信息,将新对象添加到列表中,并使用PrintDetails
  4. After输入打印列表中的所有信息,该列表被循环通过,并使用PrintDetails -method调用每个IPAddress对象。
  5. 如果用户不想继续输入IP地址,请退出

函数

我不知道如何继续,并回答我从我的老师收到是从谷歌看,所以我在这里

代码语言:javascript
复制
class IPAddress:  ##define class
        def __init__(self, IP, hostname, ASN, ISP):
            self.ip = ip
            self.hostname = hostname
            self.asn = asn
            self.isp = isp

        def PrintDetails(self):  ## construction method
            print("IP-address: " + str(self.ip) + " | Hostname: " + str(self.hostname) + " | ASN: " + str(self.asn) + "ISP: " + str(self.isp))                   


def Osio9():

    addresses = []

    while(true):
       
        ip = str (input("Enter IP address: "))  #ask for user input
        hostname = str (input("Enter Hostname: "))
        asn = str (input("Enter ASN: "))
        isp = str (input("Enter ISP: "))

        address = IPAddress
        address.isp = isp
        addresses.append(address)

        for IPAddress in addresses:
            IPAddress.PrintDetails(self)
     
            
  
 #           continueInput = str (input("Do you want to add more IP-addresses (y/n): "))
 #               if (continueInput == "y"): 
 #                  return addresses
 #
 #               else break
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-17 17:49:42

我刚刚看到了你最近的更新,其中有一些好的想法。下面是程序的一个版本,它并不完全对应于您的分配,因为主执行不是在一个循环中,而是在一个if __name__ == '__main__':语句中,它只在程序被直接调用时才会执行,而不是在导入或导入该程序的功能部分时执行。我强烈鼓励您一次尝试一小部分代码,然后根据您的具体需要对其进行调整。

让我们一片片地去:

代码语言:javascript
复制
#%% Definition of IPAddress
class IPAddress:
    def __init__(self, ip, hostname, asn, isp):
        self.ip = ip
        self.hostname = hostname
        self.asn = asn
        self.isp = isp

    def prettyprint(self):
        str2print = f' | IP: {self.ip}\n' +\
                    f' | Hostname: {self.hostname}\n' +\
                    f' | ASN: {self.asn}\n' +\
                    f' | ISP: {self.isp}\n'
        print (str2print)
    
    def __key(self):
        """
        key method to uniquely identify an object IPAddress.
        I defined it as a tuple of the 4 main attributes, but if one of them is
        unique it could be directly used as a key.
        """
        return (self.ip, self.hostname, self.asn, self.isp)
    
    def __eq__(self, other):
        """ == comparison method."""
        return isinstance(self, type(other)) and self.__key() == other.__key()
    
    def __ne__(self, other):
        """ != comparison method."""
        return not self.__eq__(other)

    def __hash__(self):
        """Makes the object hashable. Sets can now be used on IPAddress."""
        return hash(self.__key())

我正在使用spyder作为一个IDE,符号#%%创建了一些代码,非常类似于matlab,这些代码可以通过右键单击->运行单元在当前控制台中执行。

我更改了打印函数,使其更加明确。字符串对象可以由3个符号表示:'str'"str""""str"""。另外,前面的旗帜可以改变字符串的行为。最有用的是fr

使用.format()方法或f标志格式化字符串。

代码语言:javascript
复制
value = 1
str1 = 'string to format with value v = {}'.format(value)
str2 = f'string to format with value v = {value}'

您可以打印这两个字符串以确保它们是等效的。标志f类似于.format()调用。它允许在打印之前执行括号{}中的元素。当您用多个值格式化字符串时,它特别有用。

代码语言:javascript
复制
v1 = 1
v2 = 2
str1 = 'string to format with value v = {} and {}'.format(v1, v2)
str2 = f'string to format with value v = {v1} and {v2}'

我仍然选择将序列拆分成4个字符串,并将它们相加在一起,以更清晰地查看代码。每一行末尾的反斜杠\允许python将当前行和下一行视为同一行。这是一个线条分裂的角色。

注:如果您想知道标志r做什么,请查看转义字符;) r标志在处理路径时特别有用。

对象可以比较在一起。例如,如果尝试5==3,python将返回False,因为整数对象5不同于整数对象3。您可以在开发的任何对象/类中实现==!=方法。为此,我首先在函数__key()中为该对象定义一个唯一键。然后,如果两个比较对象都是从同一个类创建的,并且具有相同的键,则函数__eq__实现==并返回True。方法__ne__实现!=,如果__eq__不是True,则返回True

注:我还添加了哈希方法,以使对象可以哈希。一旦定义了键,创建一个散列就很简单了,因为这个想法是要能够唯一地标识每个对象,这也是由键完成的。这个定义允许使用集合,例如检查一个列表是否有多个相同对象的出现。

代码语言:javascript
复制
def add_IPAddress(ListOfIPAddresses, IPAddress):
    """
    Function adding IPAddress to ListOfIPAddresses if IPAddress is not already
    in ListOfIPAddresses.
    """
    if IPAddress not in ListOfIPAddresses:
        ListOfIPAddresses.append(IPAddress)
        print ('IP Address appended:')
        IPAddress.prettyprint()

def input_IPAddress():
    """
    Ask a user input to create an IPAddress object.
    """
    ip = input("Enter IP address: ")
    hostname = input("Enter Hostname: ")
    asn = input("Enter ASN: ")
    isp = input("Enter ISP: ")
    return IPAddress(ip, hostname, asn, isp)

然后,我将用户的输入和对象列表添加到两个不同的函数中。函数input()已经返回一个字符串,因此我删除了要转换的str()调用。

注意:当要求用户输入数字时,通常忘记输入是字符串,然后代码会引发错误,因为您忘记将字符串转换为整数或浮点数。

改进:我在这里没有这样做,但是通常在使用用户输入时,您必须检查输入是否正确。一些简单的语法检查(例如“.”的数目)(ipadress中的字符)已经可以提高一段代码的鲁棒性。还可以在regex中使用正则表达式来检查输入是否符合。

query_yes_no()是一个干净的、是的/不是的,我是从某个地方复制的。我通常把它放在一个util模块:环境路径中的文件夹中,名为util,其中有一个__init__.py文件。如果您查看python模块的创建,可以了解更多信息。

代码语言:javascript
复制
#%% Main
if __name__ == '__main__':
    ListOfIPAddresses = list()
    
    while True:
        if not query_yes_no('Do you want to input IP Address?'):
            break
        
        ListOfIPAddresses.append(input_IPAddress())
    
    for ipaddress in ListOfIPAddresses:
        ipaddress.prettyprint()
        print ('--------------------------') # Just pretting a separator

最后,在主体部分中,只有当用户回复no (或在query_yes_no()中定义的任何其他负面密钥)时,无限的no循环才会中断。在它被破坏之前,用户将被要求将一个新的IPAddress添加到列表ListOfIPAddresses中,如果列表ListOfIPAddresses还没有出现,这个列表就会被添加。

完整代码片段:

代码语言:javascript
复制
# -*- coding: utf-8 -*-

import sys

#%% Definition of IPAddress
class IPAddress:
    def __init__(self, ip, hostname, asn, isp):
        self.ip = ip
        self.hostname = hostname
        self.asn = asn
        self.isp = isp

    def prettyprint(self):
        str2print = f' | IP: {self.ip}\n' +\
                    f' | Hostname: {self.hostname}\n' +\
                    f' | ASN: {self.asn}\n' +\
                    f' | ISP: {self.isp}\n'
        print (str2print)
    
    def __key(self):
        """
        key method to uniquely identify an object IPAddress.
        I defined it as a tuple of the 4 main attributes, but if one of them is
        unique it could be directly used as a key.
        """
        return (self.ip, self.hostname, self.asn, self.isp)
    
    def __eq__(self, other):
        """ == comparison method."""
        return isinstance(self, type(other)) and self.__key() == other.__key()
    
    def __ne__(self, other):
        """ != comparison method."""
        return not self.__eq__(other)

    def __hash__(self):
        """Makes the object hashable. Sets can now be used on IPAddress."""
        return hash(self.__key())

#%% Functions
def add_IPAddress(ListOfIPAddresses, IPAddress):
    """
    Function adding IPAddress to ListOfIPAddresses if IPAddress is not already
    in ListOfIPAddresses.
    """
    if IPAddress not in ListOfIPAddresses:
        ListOfIPAddresses.append(IPAddress)
        print ('IP Address appended:')
        IPAddress.prettyprint()

def input_IPAddress():
    """
    Ask a user input to create an IPAddress object.
    """
    ip = input("Enter IP address: ")
    hostname = input("Enter Hostname: ")
    asn = input("Enter ASN: ")
    isp = input("Enter ISP: ")
    return IPAddress(ip, hostname, asn, isp)

#%% Util
def query_yes_no(question, default="yes"):
    """Ask a yes/no question via raw_input() and return their answer.

    "question" is a string that is presented to the user.
    "default" is the presumed answer if the user just hits <Enter>.
        It must be "yes" (the default), "no" or None (meaning
        an answer is required of the user).

    The "answer" return value is True for "yes" or False for "no".
    """
    valid = {"yes": True, "y": True, "ye": True,
             "no": False, "n": False}
    if default is None:
        prompt = " [y/n] "
    elif default == "yes":
        prompt = " [Y/n] "
    elif default == "no":
        prompt = " [y/N] "
    else:
        raise ValueError("invalid default answer: '%s'" % default)

    while True:
        sys.stdout.write(question + prompt)
        choice = input().lower()
        if default is not None and choice == '':
            return valid[default]
        elif choice in valid:
            return valid[choice]
        else:
            sys.stdout.write("Please respond with 'yes' or 'no' "
                             "(or 'y' or 'n').\n")

#%% Main
if __name__ == '__main__':
    ListOfIPAddresses = list()
    
    while True:
        if not query_yes_no('Do you want to input IP Address?'):
            break
        
        ListOfIPAddresses.append(input_IPAddress())
    
    for ipaddress in ListOfIPAddresses:
        ipaddress.prettyprint()
        print ('--------------------------') # Just pretting a separator
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64875043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档