对象没有属性'__getitem__'(类实例?)

时间:2015-06-11 07:42:35

标签: python class

这可能是一个非常简单的问题,但我对我现在的目标非常困惑。这是一个非常基础的课程:

class Book(object):
    def __init__(self, title, price):
        self.book = {'title':title, 'price':price}

当我跑这个时:

book = Book('foo', 300)
book['price']

吐出来:

TypeError: 'Book' object has no attribute '__getitem__'

我知道这不是初始化实例的常规方法,因为我使用字典。但我想知道为什么那段代码吐出了一个TypeError。我该如何解决这个问题? 提前谢谢。

PS。书籍实例的类型是类?

4 个答案:

答案 0 :(得分:13)

这是因为一个类不是一个dict对象。 访问类实例上的属性是通过点运算符完成的。

book.book['price'] 
>> 300

如果您想直接在类实例上访问dict中的键,则必须在类上实现__getitem__方法。

def __getitem__(self, key):
    return self.book[key]

book['price']
>> 300

答案 1 :(得分:6)

是。 图书图书类的对象,因为您是以这种方式初始化它。

book = Book('foo', 300)
book['price']

尝试

print book.book['price']

因此,您希望访问一个名为 book 的字典,该字典被引用为 book ,并且您想从中提取价格的值字典。

通常[]运算符查找__getitem__()方法并将请求的密钥作为参数传递。 ŁukaszR。已经证明了如何做到这一点。字典在查找切片或索引时执行键查找。

这里详细解释:https://docs.python.org/2/reference/datamodel.html

现在因为你在这里创建一个类,为什么要为类的本机必备属性创建一个单独的字典。创建类似以下示例的属性:

class Book(object):
    def __init__(self, title, price):
        self.title = 'foo'
        self.price = 300

book = Book('foo', 300)
print book.title

答案 2 :(得分:3)

book.book['price']会奏效。 要访问代理成员,您必须实施__getitem__魔术方法。

class Book(object):
    def __init__(self, title, price):
        self.book = {'title':title, 'price':price}
    def __getitem__(self, item):
        return self.book[item]

答案 3 :(得分:1)

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "log"
    "net/http"

    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
)

type API struct {
    Message string "json:message"
}
type User struct {
    ID    int    "json:id"
    Name  string "json:username"
    Email string "json:email"
    First string "json:first"
    Last  string "json:last"
}

func Hello(w http.ResponseWriter, r *http.Request) {

    // urlParams := mux.Vars(r)
    // name := urlParams["user"]
    HelloMessage := "User Creation page"

    message := API{HelloMessage}
    output, err := json.Marshal(message)

    if err != nil {
        fmt.Println("Something went wrong!")
    }

    fmt.Fprintf(w, string(output))

}

//POST A USER INTO DB
func CreateUser(w http.ResponseWriter, r *http.Request) {
    NewUser := User{}
    NewUser.Name = r.FormValue("user")
    NewUser.Email = r.FormValue("email")
    NewUser.First = r.FormValue("first")
    NewUser.Last = r.FormValue("last")
    output, err := json.Marshal(NewUser)
    fmt.Println(string(output))
    if err != nil {
        fmt.Println("Something went wrong!")
    }
    con, err := sql.Open("mysql", "root:YES@/social_network?charset=utf8")
    sqlQuery := "INSERT INTO users set user_nickname='" + NewUser.Name + "', user_first='" + NewUser.First + "', user_last='" + NewUser.Last + "', user_email='" + NewUser.Email + "'"
    q, err := con.Exec(sqlQuery)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(q)
}

//GET USERS FROM DB
func GetUsers(w http.ResponseWriter, r *http.Request) {

    db, err := sql.Open("mysql", "root:YES@/social_network?charset=utf8")
    if err != nil {
        panic(err)
    }
    err = db.Ping()
    if err != nil {
        panic(err)
    }
    defer db.Close()
    rows, err := db.Query("select * from users ")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()
    var rowBuf, _ = rows.Columns()
    var cols = make([]string, len(rowBuf))
    copy(cols, rowBuf)
    fmt.Println(rowBuf)
    var vals = make([]interface{}, len(rowBuf))
    for i, _ := range rowBuf {
        vals[i] = &rowBuf[i]
    }
    for rows.Next() {
        err := rows.Scan(vals...)
        if err != nil {
            log.Fatal(err)
        }
        var m = map[string]interface{}{}
        for i, col := range cols {
            m[col] = vals[i]
        }
        obj, _ := json.Marshal(m)
        //
        fmt.Fprintf(w, string(obj))
    }
    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }
}
func GetUser(w http.ResponseWriter, r *http.Request) {
    urlParams := mux.Vars(r)
    id := urlParams["id"]
    ReadUser := User{}
    db, err := sql.Open("mysql", "root:YES@/social_network?charset=utf8")
    stmt := db.QueryRow("select * from users where id = ?", id)
    if err != nil {
        log.Fatal(err)
    }

    err = stmt.Scan(&ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email)
    if err != nil {
        log.Fatal(err)
    }

    result, err := json.Marshal(ReadUser)
    fmt.Fprintf(w, string(result))
}
func main() {

    gorillaRoute := mux.NewRouter()
    gorillaRoute.HandleFunc("/api/user/create", CreateUser)
    gorillaRoute.HandleFunc("/api/user/read", GetUsers)
    gorillaRoute.HandleFunc("/api/user/:id", GetUser)
    http.Handle("/", gorillaRoute)
    http.ListenAndServe(":8080", nil)
}