将Python3.x自身作为对其他类的方法调用中的参数

时间:2019-02-18 09:43:58

标签: python python-3.x python-2.7 oop reference

我试图在另一个类上调用一个方法,并给被调用的类一个当前类的引用以及一些其他参数。但是以某种方式将给定的self作为参数称为被调用类的self。

让我告诉你:

import os, sys
from wsPart import wsPart
class thermo(wsPart):
    functional = False ## see line 8
    file = '/sys/bus/w1/devices/28-00000833e8ff/w1_slave' 
    def __init__(self, name, logger):
        super().__init__(name, logger)
        functional = True 
    def read(self):
        fileobject = open(self.file)
        filecontent = fileobject.read()
        fileobject.close()
        self.logger.writeLog(self,"Completed Meassurement") ##Problem on this line
        return filecontent

因此,我在其上调用类logger和方法writeLog。提供“ Parameters”消息和“ thermo”(自身)类的引用。

import datetime
from wsPart import wsPart
class logger():
    logfile = "/var/log/wheaterstation.log"
    name = "Logger"
    def writeLog(self, sender, message):
        conn = open(self.logfile, "w")
        now = str(datetime.datetime.now().isoformat())
        conn.write("[" + now + "]" + " (" + sender.getName() + "): " + message + "\n") ##Problem on this line
        conn.close()

如您所见,我放置参数self是因为它属于一个类,sender应该是对在thermo类中作为self传递的thermo类的引用。最后,还有message级别也通过了热学课程。 但这只是给我一个错误:

Traceback (most recent call last):
File "scrLib/wsControl.py", line 61, in <module>
controller = controller()
File "scrLib/wsControl.py", line 22, in __init__
self.thermo = thermo("Thermometer", logger)
File "/home/joco/git/wheaterstation/scrLib/thermo.py", line 10, in __init__
super().__init__(name, logger)
File "/home/joco/git/wheaterstation/scrLib/wsPart.py", line 8, in __init__
self.logger.writeLog(self, "created")
TypeError: writeLog() missing 1 required positional argument: 'message'

因此,在self类的self混合在一起的情况下,似乎在温度类中传递的logger参数是交织的。

你们可以在这里帮助我吗?

谢谢大家

完整的代码+其他注释可以查看Here

编辑: 记录器和温度类都在文件wsPart.py中初始化:

class controller():
    name = ""
    logger = None
    thermo = None
    dbConnector = None

    def __init__(self):
    ##THis created the controller and all the other objects
        self.name = "Controller"
        ##Create Objects
        self.logger = logger()
        self.logger.writeLog(self,"logger created") ##This line Works
        self.thermo = thermo("Thermometer", logger)
        self.dbConnector = dbConnector("DBConnector",logger)

2 个答案:

答案 0 :(得分:1)

是的,将实例和类名命名为相同的想法很糟糕。在这里:

    self.logger = logger()
    self.logger.writeLog(self,"logger created") ##This line Works
    self.thermo = thermo("Thermometer", logger)
    self.dbConnector = dbConnector("DBConnector",logger)

您正在将 class 本身传递给构造函数。因此,这些方法被视为静态/期望另一个参数。您需要更改最后两行以传递刚创建的实例:

    self.thermo = thermo("Thermometer", self.logger)
    self.dbConnector = dbConnector("DBConnector", self.logger)

更重要的是,您需要对相同对象的类和实例使用不同的名称,以避免混淆(类名称的python约定将每个单词以大写字母(驼峰)开头,例如:Logger。不要使用该约定,但是python与约定有关。

使用其他名称,您将获得NameError异常,并且您将自己修复该错误。

此外:不要在类定义中像这样“初始化”成员:

name = ""
logger = None
thermo = None
dbConnector = None

正在创建类成员,而不是实例成员。删除它们,让__init__创建实例成员,就像您当前正在做的那样。 __init__无论如何都被调用,上面的那些行只会增加混乱(除了一些特殊情况,只应以这种方式声明常量)

答案 1 :(得分:0)

完全不相关,但是注释中的代码不可读,因此我将其发布为答案:

  1. 这似乎不起作用:

    Whatever()类:     Functional = False ##参见第8行

    def __init__(self, name, logger):
        super().__init__(name, logger)
        functional = True 
    

__init__中,Python没有“暗示”此信息,您不是在创建实例属性,而是在创建局部变量。您想要self.functional = True

  1. 确保关闭文件

    def读取(自己):     fileobject =打开(self.file)     filecontent = fileobject.read()     fileobject.close()

如果open()fileobject.close()之间发生任何错误,则不保证该文件被正确关闭。您想要一个try/finally块,即

    f = open(path)
    try:
        do_something_with(f)
    finally:
        f.close()

或者更好的是with块:

    with open(path) as f:
        do_something_with(f)

这将确保关闭文件,无论发生什么情况。

  1. write模式会截断文件

    def writeLog(自身,发送者,消息):     conn =打开(self.logfile,“ w”)     现在= str(datetime.datetime.now()。isoformat())     conn.write(“ [” +现在+“]” +“(” + sender.getName()+“):” +消息+“ \ n”)##此行的问题     conn.close()

as documented,以写入模式打开文件会将该文件截断。您可能需要在这里使用“附加”模式。

  1. 当已经有一个圆形的车轮时,不要重新发明方形车轮

日志记录不只是写入文件那么简单(并发问题,需要将日志消息发送到其他目标位置,日志记录级别等),即使您不需要更多(至少在当前情况下)解决方案效率很低(打开文件很昂贵)。

Python的标准库中有一个非常全面的日志记录程序包。我完全同意,它需要学习一些正确的配置和使用方法,但是与您试图使一个幼稚的半支持自定义实现在生产中正常工作所花费的时间相比,这仍然是一个巨大的胜利,并且这是一个知识,无论如何,您将只需要任何严肃的项目。