在Python中是否存在对方法的匿名调用?

时间:2016-10-12 11:11:12

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

这是我的数据库管理员课程:

class DatabaseManager(object):
    def __init__(self):
        super().__init__()
        self.conn = sqlite3.connect('artist.db')
        self.c = self.conn.cursor()

    def create_table(self):
        self.c.execute(
            'CREATE TABLE IF NOT EXISTS artists(title TEXT, artist TEXT, album TEXT, year INTEGER, '
            'genre TEXT, ext TEXT, path TEXT, art TEXT )')
        self.c.close()
        self.conn.close()

    def insert(self, song):
        self.c.execute(
            'INSERT INTO artists(title, artist, album, year, genre, ext, path, art) VALUES(?, ?, ?, ?, ?, ?, ?, ?)',
            (song.title, song.artist, song.album, song.year, song.genre, song.ext, song.path, song.art))
        self.conn.commit()
        self.c.close()
        self.conn.close()

    def retrieve_all(self):
        self.c.execute('SELECT * FROM artists')
        data = self.c.fetchall()
        self.c.close()
        self.conn.close()
        return data

还有更多方法,但这并不重要。当我启动应用程序时,我调用create_table(),当我需要一些数据库操作时,我创建另一个对象(或重新翻译过去的对象),例如调用insert

    db = DatabaseManager()
    print(db.retrieve_artist('asdf'))
    db = DatabaseManager()
    print(db.retrieve_all())

有什么方法可以避免这种情况吗?在Java中有匿名调用: new DatabaseManager().retrieve_artist("asdf") Python中可能有类似的东西吗?

1 个答案:

答案 0 :(得分:1)

正如@Remcogerlich所说,您正在将实例化分配给变量。如果你不这样做,你可以接近你想要的。

package sodium

// Various imports, other functions and <sodium.h> here...

func init() {
    if err := sodium.Init(); err != nil {
        log.Fatalf("sodium: %s", err)
    }
}

func PasswordHash(pwd []byte, opslimit, memlimit int) ([]byte, []byte, error) {
    pwdPtr := unsafe.Pointer(&pwd[0])
    hashPtr := unsafe.Pointer(&make([]byte, C.crypto_pwhash_STRBYTES)[0])

    res := C.crypto_pwhash_str(
        (*C.char)(hashPtr),
        (*C.char)(pwdPtr),
        C.ulonglong(len(pwd)),
        C.ulonglong(opslimit),
        C.size_t(memlimit),
    )
    if res != 0 {
        return nil, pwd, fmt.Errorf("sodium: passwordhash: out of memory")
    }
    return C.GoBytes(hashPtr, C.crypto_pwhash_STRBYTES), pwd, nil
}

func MemZero(p unsafe.Pointer, size int) {
    if p != nil && size > 0 {
        C.sodium_memzero(p, C.size_t(size))
    }
}

func MemZeroBytes(bytes []byte) {
    if size := len(bytes); size > 0 {
        MemZero(unsafe.Pointer(&bytes[0]), size)
    }
}

func MemZeroStr(str *string) {
    if size := len(*str); size > 0 {
        MemZero(unsafe.Pointer(str), size)
    }
}

通过这种方式,Python执行实例化,调用您想要的方法,并且由于您不会告诉它分配给任何变量,它&#34; 消失&# 34。

您甚至可以使用类功能执行此操作,例如:

package main

// Imports etc here...

func main() {
    // Unfortunately there is no guarantee that this won't be
    // stored elsewhere in memory, but we will try to remove it anyway
    pwd := "Correct Horse Battery Staple"

    // I convert the pwd string to a []byte in place here
    // Because of this I have no reference to the new memory, with yet
    // another copy of the plain password hanging around
    // The function always returns the new []byte as the second value
    // though, so we can still zero it anyway
    hash, pwdBytes, err := sodium.PasswordHash([]byte(pwd), 6, 134217728)

    // Byte slice and string before MemZero* functions
    fmt.Println("pwd     :", pwd)
    fmt.Println("pwdBytes:", pwdBytes)

    // No need to keep a plain-text password in memory any longer than required
    sodium.MemZeroStr(&pwd)
    sodium.MemZeroBytes(pwdBytes)
    if err != nil {
      log.Fatal(err)
    }

    // Byte slice and string after MemZero* functions
    fmt.Println("pwd     :", pwd)
    fmt.Println("pwdBytes:", pwdBytes)

    // We've done our best to make sure we only have the hash in memory now
    fmt.Println("Hash:", string(hash))
}

但是,我不建议您以这种方式使用它。通常,数据库连接被建立为实例化,只要您需要使用,当您不再需要它们时,您可以安全地安全地关闭它们。我想你不是那样做的,而且浪费内存的使用,我想(如果我错了,任何人都会纠正我)。每次想要长时间使用数据库时,都可以更轻松地创建对象,一旦完成该段代码,就可以关闭连接并删除对象。