• python attribute creation


    attribute

    https://medium.com/swlh/attributes-in-python-6-concepts-to-know-1db6562057b1

    OOP中对象带有的参数,叫做 field attribute property

    python中把这种参数叫做 attribute

    In the modern programming world, object-oriented programming (OOP) languages have played an evolutionary role in changing the design and implementation patterns in software development. As a critical member of the OOP family, Python has gradually gained popularity in the last 10 years or so. Like other OOP languages, Python operates its data around a vast diversity of objects, including modules, classes, and functions.

    If you have any coding experience in any OOP language, you should probably know that all objects have their internal characteristics data called fields, attributes, or properties. In Python, these object-bound characteristics data are commonly known as attributes. In this article, I would like to talk about them, specifically in the context of a custom class.

    class attribute

    类中定义的属性。

    定义形式在 class的下一级。

    这种属性为此class拥有, 为所有此class的instance共享。

    >>> class Dog:
    ...     genus = "Canis"
    ...     family = "Canidae"
    ...
    >>> Dog.genus
    'Canis'
    >>> Dog.family
    'Canidae'
    >>> dir(Dog)
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', 
     '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', 
     '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', 
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 
     'family', 'genus']

    如上python使用 dir 函数来查看类的 属性列表。

    As shown above, we declared a class called Dog. Because all dogs belong to the Canis genus and Canidae family (Wikipedia), we created two class attributes named genus and family to store these two pieces of information. As you can see, we could directly use the class to access these attributes. We can use the introspection function dir to show the list of the Dog’s attributes, which include family and genus.

    Instance Attributes

    实例的属性,定义在 __init__ 函数中, 依附于self对象, self就是实例对象。

    这些属性为本实例独享, 每生成一个实例则这些属性都会被创建, 所以一些常量,和所有实例共享内容,都应该定义为 class属性。

    With custom classes, we can also set attributes to instance objects. These attributes are known as instance attributes, which means that they are instance-specific data. Let’s continue with the Dog class.

    In the above code, we defined the __init__ function, which will serve as the construction method to create a new Dog instance. The first argument self refers to the instance that we’re creating. During the instantiation (i.e., creating the new instance), we will assign the breed and name information to the new instance object, and these attributes will become part of the instance’s characteristics, as shown below.

    >>> class Dog:
    ...     genus = "Canis"
    ...     family = "Canidae"
    ...
    ...     def __init__(self, breed, name):
    ...         self.breed = breed
    ...         self.name = name
    ...
    >>> dog = Dog("Rottweiler", "Ada")
    >>> dog.name
    'Ada'
    >>> dog.breed
    'Rottweiler'

    Functions As Attributes

    属性不仅仅是一般变量, 还可以是函数。

    In Python, everything is an object, and previously, I already mentioned that classes are objects. Moreover, functions are Python objects. Within a class, we can define functions, which are commonly referred to as methods. Depending on how the functions are used, we can further categorize them as class methods, static methods, and instance methods. It’s not essential here to understand these differences (see my previous articles: this and that, if you want to learn them).

    Although some OOP languages treat attributes (or properties) and functions as different entities, Python considers these methods (functions) as attributes of the class — not very different as the class attributes that we defined earlier. Let’s just update the Dog class with all three kinds of methods as mentioned above: class, static, and instance methods, as shown below.

    >>> class Dog:
    ...     genus = "Canis"
    ...     family = "Canidae"
    ...
    ...     def __init__(self, breed, name):
    ...         self.breed = breed
    ...         self.name = name
    ...
    ...     @classmethod
    ...     def from_tag(cls, tag_info):
    ...         breed = tag_info["breed"]
    ...         name = tag_info["name"]
    ...         return cls(breed, name)
    ...
    ...     @staticmethod
    ...     def can_bark():
    ...         print("Yes. All dogs can bark.")
    ...
    ...     def bark(self):
    ...         print("The dog is barking.")
    >>> dir(Dog)
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', 
    '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', 
    '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', 
    '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 
    'bark', 'can_bark', 'family', 'from_tag', 'genus']

    Private Attributes

    私有属性归于本实例内部使用, 不能被实例调用者使用。

    私有属性,命名以双下划线开头, 尾部不带有下划线。不与 魔法函数冲突。

    If you have any experience in OOP, you shouldn’t be unfamiliar with the existence of access modifiers, such as public, private, and protected. These modifiers restrict the scope of where the modified attributes and functions can be accessed. However, you rarely hear such a discussion in Python. Practically, all Python attributes are public, if we borrow the terminology in the OOP world. As shown above, the class and instance attributes are all freely accessible where these classes and instances are accessible. Thus, strictly speaking, there are no real private or protected attributes (to be discussed next) in Python. We’re just using these terms analogously, such that it’ll be easier for programmers coming from other OOP background to appreciate related coding conventions (yes, just a convention, not reinforced as real access control).

    Let’s first talk about how we can define a “private” attribute in Python. The convention is to name those attributes with two leading underscores and no more than one trailing underscore. Consider the following example of the updated Dog class — for simplicity, we omit other attributes that we defined previously.

    >>> class Dog:
    ...     def __init__(self, breed, name):
    ...         self.breed = breed
    ...         self.name = name
    ...         self.__tag = f"{name} | {breed}"
    ... 
    >>> dog = Dog("Rottweiler", "Ada")
    >>> dog.name
    'Ada'
    >>> dog.__tag
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'Dog' object has no attribute '__tag'

    实际上python没有私有属性,只不过给这种属性的名称做了变化。

    After the above update, the Dog instances will have a private attribute called tag, as indicated by its name. The instance object could still access its other attributes (e.g., name) as before. However, the instance couldn’t access the private attribute __tag as we may be expecting. Indeed, such a restriction of accessing these attributes is exactly how they can be called “private” attributes. But how did it happen, under the hood? After all, I previously mentioned that all Python attributes are public by default. The following shows you how Python implements “private” attributes.

    >>> dog.__dict__
    {'breed': 'Rottweiler', 'name': 'Ada', '_Dog__tag': 'Ada | Rottweiler'}
    >>> dog._Dog__tag
    'Ada | Rottweiler'

    Protected Attributes

    保护属性, 为前缀只有一个下划线的属性。

    _xx 的属性名没有被变化,可以被直接引用到。

    意思为,可以使用,但是不鼓励。

    In the last section, we talked about private attributes, but how about protected attributes? The counterparts of protected attributes in Python are attributes whose names have only one underscore. Unlike the double underscores which will result in mangling, the single underscore prefix doesn’t change how Python interpreter handles these attributes — It’s merely a convention in the Python programming world to denote that they (i.e., the coder) doesn’t want you to access these attributes. However, again, if you insist on accessing them, you can still do that. Let’s see the code below.

    >>> class Dog:
    ...     def __init__(self, breed, name):
    ...         self.breed = breed
    ...         self.name = name
    ...         self.__tag = f"{name} | {breed}"
    ...         self._nickname = name[0]

    We updated the class Dog by creating an instance attribute called _nickname. As indicated by its name using an underscore prefix, it is considered as a “protected” attribute by convention. We can still access these protected attributes as other “public” attributes, but some IDEs or Python editors will not provide prompts (e.g., autocompletion hints) for these non-public attributes. See the screenshot for these examples using the Jupyter Notebook.

    No Auto-completion Suggestions for Non-Public Attributes

    If we work with modules instead of classes as we’re doing here, when we import the module using from the_module import *, the names with the underscore prefix won’t be imported, providing a mechanism for restricting access to these “protected” attributes.

    Properties

    property跟属性还是有差异的

    property是属性的子集, 其仅仅是函数。

    property提供的注解, 提供了对私有属性的读取控制, 和 写保护。

    Some OOP languages use attributes and properties interchangeably, but they are different concepts in Python. As discussed, attributes in Python are a broad concept that can include different kinds of attributes and functions. However, properties in Python are essentially functions that are decorated with the @property decorator. The decorated function will provide the callers with easier access to these properties. They can often be used together with the protected attributes. Let’s see an example.

    >>> class Dog:
    ...     # Same __init__ method
    ...     @property
    ...     def nickname(self):
    ...         return self._nickname
    ...
    ...     @nickname.setter
    ...     def nickname(self, new_nickname):
    ...         self._nickname = new_nickname
    ...

    属性寻找与继承

    属性寻找,遵循从下到上原则。

    先在实例上自身找, 找不到寻找其上级class对应的属性, 在上级class找不到,则继续上上找, 知道找到object

     

    属性动态添加

    https://stackoverflow.com/questions/65547821/how-to-add-attribute-to-class-in-python

    属性动态添加有两种方法(对class或者实例,都可以)

    一, 使用setattr赋值

    二,直接赋值, 例如 x.d = 1

    1
     
     

    There're two ways of setting an attribute to your class;

    First, by using setattr(class, variable, value)

    Code Syntax

    setattr(A,'c', 'c')
    print(dir(A))
    

    OUTPUT

    You can see the structure of the class A within attributes

    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
    '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
    '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
    '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
    '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
    '__weakref__', 'a', 'b', 'c']
    
    [Program finished]
    

    Second, you can do it simply by assigning the variable

    Code Syntax

    A.d = 'd'
    print(dir(A))
    

    OUTPUT

    You can see the structure of the class A within attributes

    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
    '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
    '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
    '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
    '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
    '__weakref__', 'a', 'b', 'c', 'd']
    
    [Program finished]
    

    缺点:

    对于不存在的属性访问,会抛出异常。

    这往往不是我们希望的。

    Property解决此问题

    很多库使用了 property装饰器, 来解决此问题。

    但是使用这种方法需要注意, 不能使用 hasattr 再进行属性存在性的判断, 因为这个方法会导致属性一直存在。

    https://www.datacamp.com/tutorial/property-getters-setters#:~:text=%40property%20is%20used%20to%20get%20the%20value%20of,We%20have%20to%20use%20it%20as%20a%20setter.?msclkid=16516808cf7311ec83af64cf4afa2afc

    class Property:
    
        def __init__(self, var):
            ## initializing the attribute
            self.a = var
    
        @property
        def a(self):
            return self.__a
    
        ## the attribute name and the method name must be same which is used to set the value for the attribute
        @a.setter
        def a(self, var):
            if var > 0 and var % 2 == 0:
                self.__a = var
            else:
                self.__a = 2

    property() 函数

    https://www.geeksforgeeks.org/getter-and-setter-in-python/?msclkid=c78369f8cf8911eca494095d9ff7cc41

    Using property() function to achieve getters and setters behaviour

    In Python property()is a built-in function that creates and returns a property object. A property object has three methods, getter(), setter(), and delete(). property() function in Python has four arguments property(fget, fset, fdel, doc), fget is a function for retrieving an attribute value. fset is a function for setting an attribute value. fdel is a function for deleting an attribute value. doc creates a docstring for attribute. A property object has three methods, getter(), setter(), and delete() to specify fget, fset and fdel individually. For Example

    # Python program showing a
    # use of property() function
    
    class Geeks:
        def __init__(self):
            self._age = 0
        
        # function to get value of _age
        def get_age(self):
            print("getter method called")
            return self._age
        
        # function to set value of _age
        def set_age(self, a):
            print("setter method called")
            self._age = a
    
        # function to delete _age attribute
        def del_age(self):
            del self._age
        
        age = property(get_age, set_age, del_age)
    
    mark = Geeks()
    
    mark.age = 10
    
    print(mark.age)
  • 相关阅读:
    MyBatis使用总结
    RPC与RMI的区别
    Python Web-第五周-Web Services and XML(Using Python to Access Web Data)
    Python Web-第四周-Programs that Surf the Web(Using Python to Access Web Data)
    Python Web-第三周-Networks and Sockets(Using Python to Access Web Data)
    Python Web-第二周-正则表达式(Using Python to Access Web Data)
    DELL XPS 13 9350 装Win7系统(坑爹)
    手心输入法皮肤制作技巧
    请对照这二十四条逻辑谬误自行打脸(转自知乎谢熊猫专栏)
    Aspose实现Office转PDF (ASP.NET)
  • 原文地址:https://www.cnblogs.com/lightsong/p/16251792.html
Copyright © 2020-2023  润新知