Python 使用静态名称在函数中耦合类外的变量

Python 使用静态名称在函数中耦合类外的变量,python,python-3.x,namedtuple,telnetlib,Python,Python 3.x,Namedtuple,Telnetlib,我正在使用NamedTuple定义一个服务器,我想使用telnetlib连接到该服务器。 然后我创建了一个类,该类定义了与服务器的连接,其中包含服务器详细信息和连接方法。 然后在类之外,我想使用连接方法,将服务器的NamedTuple作为连接凭据。但是,我不断得到一个错误,即连接方法缺少NamedTuple参数 我尝试将NamedTuple拉到类的外部,尝试将NamedTuple放在类的init方法内部。似乎什么都不管用 这是我的代码: import telnetlib from typing

我正在使用NamedTuple定义一个服务器,我想使用telnetlib连接到该服务器。 然后我创建了一个类,该类定义了与服务器的连接,其中包含服务器详细信息和连接方法。 然后在类之外,我想使用连接方法,将服务器的NamedTuple作为连接凭据。但是,我不断得到一个错误,即连接方法缺少NamedTuple参数

我尝试将NamedTuple拉到类的外部,尝试将NamedTuple放在类的init方法内部。似乎什么都不管用

这是我的代码:

import telnetlib
from typing import NamedTuple

class Unit(NamedTuple):
    name: str
    ip: str
    port: str

    def printunit(self, unit):
        print(unit.name)
        print(unit.ip)
        print(unit.port)

class TnCnct:
    Server1 = Unit("Server1", "1.1.1.1", "23")
    Server2 = Unit("Server2", "2.2.2.2", "23")
    Server3 = Unit("Server3", "3.3.3.3", "23")

    def __init__(self):
        pass

    def cnct(self, u):
        try:
            tn = telnetlib.Telnet(u.ip, u.port, 10)
            tn.open(u.ip, u.port)
            tn.close()
            response = u.name + " " + "Success!"
        except Exception as e:
            response = u.name + " " + "Failed!"
            print(e)
        finally:
            print(response)


TnCnct.cnct(TnCnct.Server1)
我得到的确切错误是:

TypeError: cnct() missing 1 required positional argument: 'u'

cnct
是一种需要对象实例的方法。在这里,您尝试将其作为类方法调用。 如果这是您想要的,您应该使用装饰师:

@classmethod
def cnct(cls,u):
...

1。您可能希望使用-not:

namedtuples

返回名为typename的新元组子类。新的子类用于创建类似元组的对象,这些对象具有可通过属性查找访问的字段,并且具有可索引性和可编辑性。子类的实例还有一个有用的docstring(带有typename和field_名称)和一个有用的repr()方法,该方法以name=value格式列出元组内容

vs
键入

本模块支持PEP 484和PEP 526规定的类型提示。最基本的支持包括Any、Union、Tuple、Callable、TypeVar和Generic类型。有关完整规格,请参见PEP 484。有关类型提示的简化介绍,请参见PEP 483

键入NamedTuples只是原始NamedTuples的包装器

2。您需要实例来使用instancemethods:

修复了以下两个问题:

import telnetlib
from collections import namedtuple

def printunit(self, unit):
    print(unit.name)
    print(unit.ip)
    print(unit.port)

Unit = namedtuple("Unit","name ip port")
Unit.printunit = printunit 

class TnCnct:
    Server1 = Unit("Server1", "1.1.1.1", "23")
    Server2 = Unit("Server2", "2.2.2.2", "23")
    Server3 = Unit("Server3", "3.3.3.3", "23")

    def __init__(self):
        pass

    def cnct(self, u):
        try:
            tn = telnetlib.Telnet(u.ip, u.port, 10)
            tn.open(u.ip, u.port)
            tn.close()
            response = u.name + " " + "Success!"
        except Exception as e:
            response = u.name + " " + "Failed!"
            print(e)
        finally:
            print(response)

# create a class instance and use the cnct method of it 
connector = TnCnct()
connector.cnct(TnCnct.Server1)
实例和类(方法/变量)之间的差异在此处详细说明:


哦,那太好了!我对面向对象编程非常熟悉。你能解释一下为什么没用吗?或者我是如何让它作为一个对象实例方法工作的?关于实例方法和类方法之间的区别,请参见@patrick Art答案的第二部分。另外,一个只有一个方法而不使用
self
的类通常是一个很好的转换成函数的候选对象(但这不是一个咒语,而是一个需要考虑的设计决策).Cf.例如:像OP一样使用
键入.NamedTuple
是完全有效的。试试看。@FrancisColas确实是这样…看看-它在内部也使用collections.NamedTuple,它只是围绕collections.NamedTuple的一个包装器-那么为什么不使用正确的模块开始使用间接寻址呢?这就是对于Python中的可选类型,您可以使用它来提供类型信息(这是一个好主意)。如果您不想这样做,也可以;但您最初的声明是“您需要使用集合中的namedtuples”(emphasis mine),这既不是问题的重点,也不是对其代码的实际改进。您将其更正为“May want”但这仍然是一个分心相对于你的答案,这实际上是好的。