2016-04-23 94 views
2

我有幾類,從進口繼承一個模塊:迭代通過模塊的類(而不是進口)在Python

# electric_cars.py 

from cars import ElectricCar 

class Tesla(ElectricCar): 
    name = "Tesla" 

class Faraday(ElectricCar): 
    name = "Faraday" 

class Zoe(ElectricCar): 
    name = "Zoe" 

從不同的模塊,我做了以下內容:

# initiate_cars.py 

import electric_cars 
import tradi_cars 
import flying_cars 

import inspect 

cls_electric_cars = inspect.getmembers(electric_cars, inspect.isclass) 
cls_tradi_cars = inspect.getmembers(tradi_cars, inspect.isclass) 
cls_flying_cars = inspect.getmembers(flying_cars, inspect.isclass) 

all_cars = [] 

for cls_car in cls_electric_cars + cls_tradi_cars + cls_flying_cars: 
    # inspect.getmembers returns a list of tuples 
    # with the class as each tuple's second member 
    all_cars.append(cls_car[1]) 

除了一個問題,一切都很好:每個模塊的進口electric_cars,tradi_cars, flying_cars進入all_cars

所以這與上面的代碼,all_cars開始:

[ 
    <class 'car.ElectricCar'>,  # i don't want this 
    <class 'cars.electric_cars.Tesla'>, 
    <class 'cars.electric_cars.Faraday'>, 
    <class 'cars.electric_cars.Zoe'>, 
    <class 'car.TradiCar'>,   # i don't want this 
    <class 'cars.tradi_cars.Pontiac'>, 
    <class 'cars.tradi_cars.Chevrolet'>, 
    <class 'cars.tradi_cars.Chrysler'>, 
    <class 'car.FlyingCar'>,   # i don't want this 
    <class 'cars.flying_cars.SpaceX'> 
] 

有沒有辦法,不使一個複雜的父類加載和issubclass檢查,以排除由inspect.getmembers()加載的類import S'

- 爲了預測在你-shouldn't-DO,這可能與這樣一個問題出現的話,這個工程的最終目標是能夠簡單地在任意的electric_cars.py加個班, tradi_cars.pyflying_cars.py並且無需其他任何操作即可使用。如果你想到其他方式做到這一點,歡迎提出想法。

+1

只是讓'all_cars = ElectricCar .__子類__()+ TradiCar .__子類__()+ ...'更容易嗎?那麼你根本不需要用「檢查」。 – jonrsharpe

+0

@jonrsharpe做了詭計 - 我不知道這種方法!如果您將您的評論轉換爲答案,我會接受它(這可能對其他人有用) - 謝謝! – Jivan

+1

如果這就是答案,這個問題已經存在:http://stackoverflow.com/q/3862310/3001761 – jonrsharpe

回答

1

一個簡單的解決方案是更改在electric_cars模塊中導入ElectricCar的方式。而不是from cars import ElectricCar,你可以只import cars,然後在你的class語句中使用完全合格的叫法:

import cars 

class Tesla(cars.ElectricCar): 
    ... 

另一種方法是寫自己的predicate價值爲inspect.getmembers叫你正在做的:

inspect.getmembers(electric_cars, lambda x: inspect.isclass(x) and 
              x.__module__ == electric_cars.__name__)