[英]What is the proper way to use @property in python
我有以下代碼,Dog和Cat類是從Animal類繼承的。 而Person類使用Dog和Cat類作為其實例。 我想有一個函數來返回實例名稱,例如字符串“獲取名稱xxx”作為john實例和john的屬性dog(貓的名字)。 我已經嘗試在Animal class和Person下編寫屬性namegetter ,我可以得到想要的東西。 但是,是否有適當的方法呢? 因此,如果我有幾個像Person這樣的班級,則無需在該班級下編寫相同的屬性
class Animal(object):
def __init__(self, name):
self.name = name
@property
def namegetter(self):
return 'get the name of {}'.format(self.name)
class Cat(Animal):
def __init__(self, food, name):
super().__init__(name)
self.food = food
self.sound = 'meow'
class Dog(Animal):
def __init__(self, food, name):
super().__init__(name)
self.food = food
self.space = 'park'
class Person(object):
def __init__(self, name):
self.name = name
self.dog = Dog("dog's food", "dog's name" )
self.cat = Cat("dog's food", "cat's name")
@property
def namegetter(self):
return 'get the name of {}'.format(self.name)
if __name__ == '__main__':
john = Person('john')
print(john.name) #john
print(john.dog.name) #dog's name
print(john.cat.name) #cat's name
print(john.dog.namegetter) #get the name of dog
print(john.cat.namegetter) #get the name of cat
print(john.namegetter) #get the name of john
根據評論,我想您想避免兩次定義相同的方法。 您可以使用Mixins(在復雜的層次結構中)或僅另一個基類來做到這一點。 至於您是否可以避免編寫@property
:可以省略它,但是隨后您必須在方法namegetter()
后面寫括號。
使用基類的示例:
class NamedEntity(object):
def __init__(self, name):
self.name = name
@property
def namegetter(self):
return 'get the name of {}'.format(self.name)
class Animal(NamedEntity):
pass
class Cat(Animal):
def __init__(self, food, name):
super(Cat, self).__init__(name)
self.food = food
self.sound = 'meow'
class Dog(Animal):
def __init__(self, food, name):
super(Dog, self).__init__(name)
self.food = food
self.space = 'park'
class Person(NamedEntity):
def __init__(self, name):
super(Person, self).__init__(name)
self.dog = Dog("dog's food", "dog's name" )
self.cat = Cat("dog's food", "cat's name")
if __name__ == '__main__':
john = Person('john')
print(john.name) #john
print(john.dog.name) #dog's name
print(john.cat.name) #cat's name
print(john.dog.namegetter) #get the name of dog
print(john.cat.namegetter) #get the name of cat
print(john.namegetter) #get the name of john
在一個更復雜的示例中,您可以改用Mixin,這將基本上改變您在類定義中從它繼承的方式:
class NamedEntityMixin(object):
def __init__(self, name):
self.name = name
@property
def namegetter(self):
return 'get the name of {}'.format(self.name)
class Animal(NamedEntityMixin, object):
# Imagine object being another parent class with additional properties and methods
pass
class Cat(Animal):
def __init__(self, food, name):
super(Cat, self).__init__(name)
self.food = food
self.sound = 'meow'
class Dog(Animal):
def __init__(self, food, name):
super(Dog, self).__init__(name)
self.food = food
self.space = 'park'
class Person(NamedEntityMixin, object):
# Imagine object being another parent class with additional properties and methods
def __init__(self, name):
super(Person, self).__init__(name)
self.dog = Dog("dog's food", "dog's name" )
self.cat = Cat("dog's food", "cat's name")
if __name__ == '__main__':
john = Person('john')
print(john.name) #john
print(john.dog.name) #dog's name
print(john.cat.name) #cat's name
print(john.dog.namegetter) #get the name of dog
print(john.cat.namegetter) #get the name of cat
print(john.namegetter) #get the name of john
在評論中,您詢問有人是否要寫給namegetter
。 上面,我只定義了只讀訪問權限,因為namegetter
這個名字聽起來像是您需要的那樣。 下面,我為您定義了一個帶有getter和setter的版本,允許您設置格式字符串,並根據需要替換可選變量{name}
:
class NamedEntity(object):
def __init__(self, name):
self.name = name
self._namegetter = "get the name of {name}"
def _get_namegetter(self):
return self._namegetter.format(name=self.name)
def _set_namegetter(self, namegetter):
self._namegetter = namegetter
namegetter = property(_get_namegetter, _set_namegetter)
class Animal(NamedEntity):
pass
class Cat(Animal):
def __init__(self, food, name):
super(Cat, self).__init__(name)
self.food = food
self.sound = 'meow'
self.namegetter = 'catnamegetter'
class Dog(Animal):
def __init__(self, food, name):
super(Dog, self).__init__(name)
self.food = food
self.space = 'park'
class Person(NamedEntity):
def __init__(self, name):
super(Person, self).__init__(name)
self.dog = Dog("dog's food", "dog's name" )
self.cat = Cat("dog's food", "cat's name")
if __name__ == '__main__':
john = Person('john')
print(john.name) #john
print(john.dog.name) #dog's name
print(john.cat.name) #cat's name
print(john.dog.namegetter) #get the name of dog
print(john.cat.namegetter) #get the name of cat
print(john.namegetter) #get the name of john
我將getter和setter分為兩個方法,並將它們用作namegetter
屬性。 Python將根據您自動訪問屬性的方式選擇正確的方法。
但是上述解決方案不再使用裝飾器,這可能會使代碼的可讀性降低。 一個帶有裝飾器的版本是這個。 請注意,方法namegetter
使用不同的裝飾器定義了兩次:
class NamedEntity(object):
def __init__(self, name):
self.name = name
self._namegetter = "get the name of {name}"
@property
def namegetter(self):
return self._namegetter.format(name=self.name)
@namegetter.setter
def namegetter(self, namegetter):
self._namegetter = namegetter
class Animal(NamedEntity):
pass
class Cat(Animal):
def __init__(self, food, name):
super(Cat, self).__init__(name)
self.food = food
self.sound = 'meow'
self.namegetter = 'catnamegetter'
class Dog(Animal):
def __init__(self, food, name):
super(Dog, self).__init__(name)
self.food = food
self.space = 'park'
class Person(NamedEntity):
def __init__(self, name):
super(Person, self).__init__(name)
self.dog = Dog("dog's food", "dog's name" )
self.cat = Cat("dog's food", "cat's name")
if __name__ == '__main__':
john = Person('john')
print(john.name) #john
print(john.dog.name) #dog's name
print(john.cat.name) #cat's name
print(john.dog.namegetter) #get the name of dog
print(john.cat.namegetter) #get the name of cat
print(john.namegetter) #get the name of john
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.