[英]How to inherit a python base class?
dir/
|
|___ __init__.py
|
|___ Base_class.py
|
|___ Subclass.py
__init__.py
是空的(如提到這里 )
/* Base_class.py
class Employee:
numOfEmployees = 0 # Pure class member, no need to override
raiseAmount = 1.04 # Could not be pure class member, so, can it be overidden by object?
# Yes. make sense
# This is why we use self.raiseAmount in methods
def __init__(self, firstName, lastName, pay):
self.firstName = firstName
self.lastName = lastName
self.pay = pay
self.email = firstName + '.' + lastName + '@email.com'
Employee.numOfEmployees += 1
def fullName(self):
return '{} {}'.format(self.firstName, self.lastName)
def appyRaise(self):
self.pay = int(self.pay * self.raiseAmount)
@classmethod
def setRaiseAmt(cls, amount):
cls.raiseAmount = amount
@classmethod
def createEmployee(cls, employeeStr):
firstName, lastName, pay = employeeStr.split('-')
return cls(firstName, lastName, pay)
@staticmethod
def isWorkDay(day):
if day.weekday() == 5 or day.weekday() == 6:
return False
return True
emp1 = Employee('AAA', 'BBB', 50000)
emp2 = Employee('CCC', 'DDD', 40000)
print Employee.raiseAmount # 1.04
print emp1.raiseAmount # 1.04
print emp2.raiseAmount # 1.04
# Regular methods
emp1.fullName() # Executing fullName(<__main__.Employee object at 0xb7dbef0c>)
Employee.fullName(emp1) # same as above
# With classmethods, the class of the object instance is implicitly passed as the first argument instead of self.
Employee.setRaiseAmt(1.05) # class variable's cls member raiseAmount will get updated
print Employee.raiseAmount # 1.05
print emp1.raiseAmount # 1.05
print emp2.raiseAmount # 1.05
emp1.setRaiseAmt(1.05) # Invokes as, setRaise(<class '__main__.Employee'>,1.05)
# Application of class methods as constructors
employeeStr = 'John-Doe-70000'
newEmployee = Employee.createEmployee(employeeStr);
print newEmployee.email
print newEmployee.pay
# With static methods, neither self (the object instance) nor cls (the class) is implicitly passed as the first argument. They behave like plain functions except that you can call them from an instance or the class:
emp1 = Employee('AAA', 'BBB', 50000)
emp2 = Employee('CCC', 'DDD', 40000)
import datetime
myDate = datetime.date(2016, 7, 10)
print emp1.isWorkDay(myDate) # Executing isWorkDay(myDate)
/* Subclass.py */
from Base_class import Employee
class Developer(Employee):
pass
題:
在僅繼承Employee
類上:
> python Subclass.py
為什么這下面的輸出? 如何繼承基類?
$ python Subclass.py
1.04
1.04
1.04
1.05
1.05
1.05
John.Doe@email.com
70000
False
你似乎遇到的問題是,當你import
一個模塊,它的所有代碼的運行,即使您正在使用from module import name
語法剛剛導入的模塊的內容的一部分。 這就是為什么從運行Subclass.py
文件中獲得與運行Base_class.py
相同的輸出的Base_class.py
。
如果您不希望在導入Base_class
模塊時運行測試代碼,則應將其放在if __name__ == "__main__":
塊中。 全局變量__name__
通常是模塊的名稱(例如"Base_class"
)。 當您將模塊作為腳本運行時,它是"__main__"
。 因此,測試該字符串可以使您僅在模塊是主腳本時才運行某些代碼,而不是在其他模塊導入該腳本時才運行。
您可能還對子類如何看其父類的屬性感到困惑。 這在Python中有點神奇。 在實例上查找屬性時,首先會檢查實例自己的字典,然后是類的字典,然后是其MRO(方法解析順序,通常是父類鏈)中每個基類的字典,除非您正在執行復雜的多重繼承)。 因此,除非您在Developer
類上為其顯式設置新值,否則Employee
的繼承屬性將不會顯示在Developer.__dict__
。
據我所知,如果您創建一些Developer
實例並調用它們將繼承的某些方法,則您的代碼應該可以正常工作。 看到的唯一錯誤是Employee
中的修飾方法與其他方法的縮進方式不同,但是我懷疑(基於您說的輸出結果)這是將代碼復制到Stack Overflow的問題,而不是真正的錯誤。 您可能要仔細檢查一下,是否沒有混合使用縮進的空格和制表符,這可能導致難以發現的細微錯誤(並且Python 3中不允許混合使用)。
您已將setRaiseAmt
聲明為類方法,這意味着無論您是通過類還是通過實例調用raiseAmount
,它都會更新類變量raiseAmount
。 不需要這種方法。 如果要更改默認的加注金額,請直接執行以下操作:
Employee.raiseAmount = ...
如果要設置單個員工的價值,也可以直接通過實例進行設置:
emp1.raiseAmount = ...
這總是在實例的屬性字典中創建(或更新)變量。 在讀取 raiseAmount
的值時,將獲得實例屬性的值(如果存在),否則將獲得類屬性的值。
如果必須提供設置器(例如,這是類分配的要求),請提供單獨的類和實例方法:
@classmethod
def set_default_raise_amount(cls, amount):
cls.raise_amount = amount
def set_raise_amount(self, amount):
self.raise_amount = amount
當您導入Employee基類時,首先將Base_class.py文件讀入內存並進行處理,然后將Employee
類導入到Subclass.py
的名稱空間中。
要測試您是否成功繼承了子類,可以在Subclass.py
嘗試實例化Employee類,盡管您需要創建一個構造函數。
將它們添加到您的Developer
類。
from Base_class import Employee
class Developer(Employee):
def __init__(self):
Super(Employee, self).__init__()
test_dev = Developer('Bob', 'Marley', 1000)
test_dev.fullName()
從Base_class.py導入Employee時,它將整個Base_class.py數據讀取到內存中。 因此,因為您在該文件內創建對象並在Base_class.py中打印它們,所以在設置繼承時將執行它們。
您可能要通過main.py之類的其他文件來創建那些Employee對象。 當您導入Employee類時,這將阻止您處理打印和對象創建請求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.