class 变量在 for 循环中保持为空

class variable stays empty with for loop

我想确保 hotel_name 不存在于 Hotel.hotels 列表中。 好像每次for循环开始喂食的时候都在空列表中查找。

请注意,如果我没有使用 for 循环而只执行

Hotel.hotels.append([number,hotel_name,city,total_number,empty_rooms])

它打印酒店列表

[[1, 'Crown Plaza', 'alex', 20, 2], [1, 'Crown Plaza', 'alex', 20, 2], [2, 'Radisson Blu', 'cairo', 24, 22], [3, 'Paradise Inn', 'dubai', 390, 200], [4, 'Four Seasons', 'alex', 1000, 400], [5, 'Address', 'dubai', 500, 200], [6, 'Fairmont', 'dubai', 1000, 100], [7, 'Rotana', 'dubai', 5000, 300]]
[Finished in 0.1s]

这是文件

class Hotel():
    """""""""
    this is hotel class file
    """
    hotels = []

    def __init__(self,number,hotel_name,city,total_number,empty_rooms):
        self.number = number
        self.hotel_name = hotel_name
        self.city = city
        self.total_number = total_number
        self.empty_rooms = empty_rooms
        for i in Hotel.hotels:
            if self.hotel_name not in i:
                Hotel.hotels.append([number,hotel_name,city,total_number,empty_rooms])
            # else:
            #     print "Hotel already exists!"

feed_dataBase_with_hotel = Hotel(1,"Crown Plaza","alex",20,2)
feed_dataBase_with_hotel = Hotel(1,"Crown Plaza","alex",20,2)# cull repeated
feed_dataBase_with_hotel = Hotel(2,"Radisson Blu","cairo",24,22)
feed_dataBase_with_hotel = Hotel(3,"Paradise Inn","dubai",390,200)
feed_dataBase_with_hotel = Hotel(4,"Four Seasons","alex",1000,400)
feed_dataBase_with_hotel = Hotel(5,"Address","dubai",500,200)
feed_dataBase_with_hotel = Hotel(6,"Fairmont","dubai",1000,100)
feed_dataBase_with_hotel = Hotel(7,"Rotana","dubai",5000,300)

print Hotel.hotels

非常感谢帕特里克的回答 更新 如果我想从 dict 构建一个列表,因为我想访问空房间并用另一个 class

更改它的值怎么办
class Hotel():
    """
    this is hotel class file
    """
    hotels = {}
    hotelList = []

    def __init__(self,number,hotel_name,city,total_number,empty_rooms):
        self.number = number
        self.hotel_name = hotel_name
        self.city = city
        self.total_number = total_number
        self.empty_rooms = empty_rooms

        # edited: no for needed
        if self.hotel_name in Hotel.hotels:
            print('Hotel {} Already exists!'.format(self.hotel_name))
            return # or raise ValueError & handle it

        Hotel.hotels[self.hotel_name] = self

        tempList = Hotel.hotels.items()
        for i in tempList:
            x = Hotel.hotels.items()[i][1]
            Hotel.hotelList.append(x)

更新

另一个class用于预订将使用我们在酒店class

中使用的实例变量hotel_name
from hotel import Hotel
from customer import Customer
from notification import Notification

class Reservation():
    reservations =[]
    def reserve_room(self,hotel_name, customer_name):
        x = Hotel.hotels.values()
        for i in x:
            if Hotel.hotel_name in i:
                Reservation.reservations.append([hotel_name,customer_name])
                i[4] -=1

AttributeError: class 酒店没有属性 'hotel_name'

更新 来自 使用

def __getitem__(self, hotel_name):
          return self.hotel_name

问题已解决!

特别感谢Patrick

看看这一行 for i in Hotel.hotels: here

for i in Hotel.hotels:
    if self.hotel_name not in i:
          Hotel.hotels.append([number,hotel_name,city,total_number,empty_rooms])

并尝试找出在哪种情况下它会填满你的数组

问题是您在遍历空 "hotels" 列表时 .append。 从检查 for 循环中是否存在 hotel_name 开始,稍后追加。

for hotel in self.hotels:
    if self.hotel_name == hotel[1]:  # hotel_name is at index 1
        print('Already exists!')
        return  # return before appending
#now append
self.hotels.append([number,hotel_name,city,total_number,empty_rooms])

如果你不想return,试试这个

for hotel in self.hotels:
    if self.hotel_name == hotel[1]:  # hotel_name is at index 1
        print('Already exists!')
        break
else:  # break did not happen
    self.hotels.append([number,hotel_name,city,total_number,empty_rooms])

我建议改变一些东西来修复它:

  • 您正在迭代可能的 1000 个 Hotel 的列表以查找是否有相同的名称,如果您使用 setdict 因为其中的查找是 O(1)Lists 有 O(n) 查找最坏情况时间,这意味着 set/dict 是常数时间,无论你有多少 Hotels。列表变得越来越慢,您需要搜索的 Hotel 越多。

  • 你用新的酒店实例覆盖同一个变量,它们自己被创建并被遗忘 - 你只将它们的值存储在你的 Hotel.hotels 列表中而不是存储构造的 Hotel 本身。 Hotel 个实例的整个构造毫无意义。

提议的更改:

  • 使静态存储成为字典,让您可以快速查找
  • 存储您的 Hotel 实例,而不是您使用
  • 创建的 Hotel 的值
  • 不要直接打印 Hotel.hotelDict - 我介绍了一种方法,它只接受你的 dicti 的值并按顺序打印它们 - 默认情况下我按 Hotel.number
  • 排序

class Hotel():
    """""""""
    this is hotel class file
    """   
    hotelDict = {} # checking "in" for sets is much faster then list - a dict is similar
                   # fast in checking and can hold values - serves double duty here
    # sorted hotels by value, sorted by key

    @classmethod
    def getSortedHotels(cls, sortKey = lambda x:x.number):
        """Takes all values (Hotel's) from Hotel.hotelDict
        and prints them after sorting. Default sort key is Hotel.number"""
        return sorted(cls.hotelDict.values(), key=sortKey) 

    def __init__(self,number,hotel_name,city,total_number,empty_rooms):
        if hotel_name in Hotel.hotelDict:
            print("Hotel already exists: {}".format(hotel_name))
            return # or raise ValueError("Hotel already exists") and handle the error
# see 
# if you want to try to replace it using __new__() but not sure if its possible

        self.number = number
        self.hotel_name = hotel_name
        self.city = city
        self.total_number = total_number
        self.empty_rooms = empty_rooms
        Hotel.hotelDict[self.hotel_name] = self

    def __repr__(self):
        """Neater print output when printing them inside a list"""
        return "{:>3}) {} in {} has {} of wich {} are empty.".format(
        self.number,self.hotel_name,self.city,self.total_number,self.empty_rooms)
        # if you want a "simple" list-like output of your attributes:
        # comment the return above and uncomment:
        # return repr([self.number,self.hotel_name,self.city,
        #              self.total_number,self.empty_rooms])

    def __str__(self):
        """Neater print output when printing Hotel instances"""
        return self.__repr__()

测试:

feed_dataBase_with_hotel = Hotel(1,"Crown Plaza","alex",20,2)
feed_dataBase_with_hotel = Hotel(1,"Crown Plaza","alex",20,2) # cull repeated
feed_dataBase_with_hotel = Hotel(2,"Radisson Blu","cairo",24,22)
feed_dataBase_with_hotel = Hotel(3,"Paradise Inn","dubai",390,200)
feed_dataBase_with_hotel = Hotel(4,"Four Seasons","alex",1000,400)
feed_dataBase_with_hotel = Hotel(5,"Address","dubai",500,200)
feed_dataBase_with_hotel = Hotel(6,"Fairmont","dubai",1000,100)
feed_dataBase_with_hotel = Hotel(7,"Rotana","dubai",5000,300)

print Hotel.getSortedHotels() 

print Hotel(99,"NoWayInn","NoWhere",1,200)

输出:

Hotel already exists: Crown Plaza
[  1) Crown Plaza in alex has 20 of wich 2 are empty.,   
   2) Radisson Blu in cairo has 24 of wich 22 are empty.,   
   3) Paradise Inn in dubai has 390 of wich 200 are empty.,   
   4) Four Seasons in alex has 1000 of wich 400 are empty.,   
   5) Address in dubai has 500 of wich 200 are empty.,   
   6) Fairmont in dubai has 1000 of wich 100 are empty.,   
   7) Rotana in dubai has 5000 of wich 300 are empty.]

 99) NoWayInn in NoWhere has 1 of wich 200 are empty.

如果您希望酒店按名称排序,很简单:

print Hotel.getSortedHotels(sortKey=lambda x:x.hotel_name)